LINUX.ORG.RU

Какой смысл привести переменную num к типу double, ибо функция sqrt() и так принимает аргумент типу double?

Никакого, просто КГ/АМ.

anonymous
()
Ответ на: комментарий от RazrFalcon

В gcc нет, в clang тоже нет. Но можно пересобрать компилятор с нужными опциями. Или включить их в системе сборки.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от DELIRIUM

Это понятно. Только там таких опций 100500. Но это не значит, что их все нужно включать.

Достаточно посмотреть на Qt, у которого c-style cast для примитивов на каждом шагу.

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

Я код qt почти не видел, но это не означает, что это хорошая практика. Сишный каст убирает const, а это не есть гуд.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от DELIRIUM

Пфф, скобочки по другому расставить и всё

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
    int num;
    double sq_root;
    
    for (num=1; num < 100; num++) {
        sq_root = sqrt(double(num));
        cout << num << " " << sq_root << '\n';
    }
    
    return 0;
}

fluorite ★★★★★
()
Последнее исправление: fluorite (всего исправлений: 1)
Ответ на: комментарий от aureliano15

Правильно вот так:

int main()
{
    constexpr auto NUM_MAX{99};
    for (size_t i = 1; i <= NUM_MAX; ++i) {
        const auto sq_root = std::sqrt(static_cast<double>(i));
        std::cout << i << ' ' << sq_root << '\n';
    }
}

использовать для них одну переменную i немного эффективнее
имхо

Потому ты и вырос таким.

создавать

Ахаха.

Найди лишнюю инструкцию:

https://pastebin.com/aQ5Vd5Pa

https://pastebin.com/ddAyuVUt

К тому же иногда требуется значение этой переменной вне тела цикла.

Как тебе план далеть что-то в тех случаях, когда это необходимо?

описания в одном месте (хотя это уже на вкус и цвет...)

Declaring variables «at the top of the function» is always a disastrously bad practice. Even in C89/90 language, where variables can only be declared at the beginning of the block, it is better to declare them as locally as possible, i.e. at the beginning of smallest local block that covers the desired lifetime of the variable. Sometimes it might even make sense to introduce a «redundant» local block with the only purpose of «localizing» the variable declaration.

различие между сями и крестами - в отсутствии в сях и в наличии в крестах ООП

Ты что, кретин? И в C есть ООП, и в C++ есть ООП.

BruteForce ★★★
()
double sqrt(double val)
{
   return ::sqrt(val);
}

double sqrt(int val)
{
   return val;
}
andreyu ★★★★★
()
Ответ на: комментарий от aureliano15

Хорошо, приведите мне реальный пример, где программа падала бы или работала некорректно из-за того, что переменные не были инициализированы сразу (но были инициализированы до первого использования).

На правах быдлокода:

#include <сstdlib>

int main(int argc, char* argv[])
{
   const int count = atoi(argv[1]);

   int i, j;
   for (i = 0; i < count; i++)
   {
      for (j = 0; j < 10; j++)
      {
         // do some stuff
      }
   }
   
   return j;
}
$ ./a.out 0
andreyu ★★★★★
()
Ответ на: комментарий от RazrFalcon

используй static_cast, а не сишный

А смысл? Для примитивов разницы не будет. У нас же не динамический полиморфизм тут.

Поиск всех кастов с помощью grep или подобного в коде.

andreyu ★★★★★
()
Ответ на: комментарий от i-rinat

for (double i = 1; i != NUM_MAX + 1; ++i) {

Тогда уж так:

for (double i = 1; i != NUM_MAX + 1; i += 1.0) {


Но лучше так никогда не писать вообще.

andreyu ★★★★★
()
Ответ на: комментарий от BruteForce

/facepalm

Чойта-чоэта?

/facepalm²

Ну-ка, ну-ка, объясни, что не так?

i-rinat ★★★★★
()
Ответ на: комментарий от Mg_usr

На что? На переменную в стеке, которая создается один раз?

Aswed ★★★★★
()
Ответ на: комментарий от RazrFalcon

Сомнительная польза.

Когда понадобится в большом проекте сделать такой поиск, то ваше мнение может измениться.

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

программа падала бы или работала некорректно из-за того, что переменные не были инициализированы сразу (но были инициализированы до первого использования).

На правах быдлокода:

Хоть формально в данном примере переменная j не инициализируется вообще, а не только сразу, т. к. внутренний цикл не выполняется, но принято: такое, имхо, вполне может быть в неаккуратном коде или при модификации ранее написанного кода.

Спасибо за пример, он удачный.

aureliano15 ★★
()
Ответ на: комментарий от RazrFalcon

приведите мне реальный пример, где программа падала бы или работала некорректно из-за того, что переменные не были инициализированы сразу (но были инициализированы до первого использования).

Мне картинку нарисовать, чтобы вы поняли суть вопроса?

Я не просил рисовать картинок, а всего лишь привести пример. Впрочем, за вас это сделал andreyu в этом сообщении. Его вариант принимается.

А если у меня не вектор, а статический массив?

И вы не знаете размер статического массива? Что за бред?

Ситуации бывают разные. В буфер фиксированной длины могут быть загружены данные переменной длины, не больше заданной. Это может быть вообще какой-то фиксированный адрес памяти. Или меня может интересовать не весь массив, а только его часть (например, при реализации функции типа strchr, я прерываю цикл и возвращаю индекс первого подходящего символа в строке).

завершился ли цикл досрочно (брейком) или нет

Я считаю, что в данном случае лучше завести отдельный флаг, чем полагаться на счётчик.

Чем лучше, кроме того, что вместо одной переменной будут задействованы 2 + лишняя операция присвоения?

При чём тут метки - не ясно. Их нету в C/C++.

Приехали! Это с каких пор их нет в си/си++? Может и оператора goto тоже нет?

нас со Страуструпом

Корона не жмёт, ставиться себя на один уровень со Страуструпом?

А я и не ставлю. Это вы нас двоих в клинику предлагаете унести.

А ещё исключения

Да, это тоже. Спасибо, что напомнили.

constexpr

Вот без этого вполне себе можно прожить. Оптимизатор и без того обычно рассчитывает константные выражения на этапе компиляции. Хотя с тем, что лучше полагаться на код, а не на особенности оптимизатора, соглашусь.

std [skip] неймспейсы

И зачем оно нужно? Чтоб создавать функции и классы с одинаковыми названиями в разных пространствах, а потом путаться? Не проще ли сразу придумать оригинальное название? И не надо надуманных примеров, когда есть 2 сферические библиотеки в вакууме с одинаковыми названиями функций. Если библиотека популярна, другие обычно называют свои функции по-другому, а если нет, то можно и переименовать, если что.

auto

Это чтоб название типа в описании не писать? Очень нужная фича.

ссылки

Ну да, удобно, но не намного удобнее, чем указатели. Я понимаю, что ссылки ещё и безопаснее, но включить эту фичу в список возможностей, которые делают си++ _принципиально другим_ языком, не могу.

нормальный const

Ну а в си макросы. Да, я знаю, что макросы - это не так строго и безопасно, но ещё раз: да, бо́льшая строгость си++ мне импонирует, но не это главное.

статическая типизация

А в си какая типизация?

raii

Ага, а ещё инкапсуляция, наследование и полиморфизм. Открою тайну: всё вместе это и называется ооп.

При чём тут шаблоны и ООП?

При том, что большая часть stl реализована с помощью шаблонных классов. Хотя шаблоны, конечно, не обязаны быть классами.

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

что вместо одной переменной будут задействованы 2 + лишняя операция присвоения?

Экономия на спичках.

Может и оператора goto тоже нет?

Я не про goto, а про метки. Пример: https://rustbyexample.com/flow_control/loop/nested.html

Это вы нас двоих в клинику предлагаете унести.

Только одного.

Вот без этого вполне себе можно прожить.

Ваше имхо никого не волнует. Разговор о фичах C++, которых нет в С.

И зачем оно нужно?

Ваше имхо никого не волнует. x2

И всё в этом духе. Начинали про то, что C++ отличается от С только наличием ООП, а после предоставленных примеров скатили обсуждение во вкусовщину.

А в си какая типизация?

Слабая. Я попутал строгую и статическую.

Открою тайну: всё вместе это и называется ооп.

Открою тайну - в Java/C# живут без raii, но там есть ООП.

При том, что большая часть stl реализована с помощью шаблонных классов.

Связи ноль.

RazrFalcon ★★★★★
()
Ответ на: комментарий от BruteForce

Правильно вот так:

И так правильно, и как было, - тоже правильно. Синтаксис не запрещает, и в твоём коде я не вижу никаких преимуществ, впрочем, как и недостатков.

std::cout << i << ' ' << sq_root << '\n';

Странно, что ты поставил в конце '\n', а не std::endl, как рекомендует большинство руководств по си++. Впрочем, я не такой педант и придираться к разной ерунде не буду.

К тому же иногда требуется значение этой переменной вне тела цикла.

Как тебе план далеть что-то в тех случаях, когда это необходимо?

Именно так я и делаю. В чём проблема?

описания в одном месте (хотя это уже на вкус и цвет...)

Declaring variables «at the top of the function» is always a disastrously bad practice. Even in C89/90 language, where variables can only be declared at the beginning of the block, it is better to declare them as locally as possible, i.e. at the beginning of smallest local block that covers the desired lifetime of the variable. Sometimes it might even make sense to introduce a «redundant» local block with the only purpose of «localizing» the variable declaration.

Вот раньше утята вместо того, чтоб включить голову, просто находили цитату из какого-нибудь авторитета и постили её, не объясняя, чем оно лучше (типа так партия сказала). Современные утята совсем обленились и им влом даже нагуглить нужную цитату от какого-нибудь уважаемого эксперта. Вместо этого они берут первую попавшуюся реплику с форума (в данном случае со https://stackoverflow.com/questions/3773396/declare-variables-at-top-of-funct...), лишь бы было по-англицки (так круче), и даже не приводят ссылку на источник (авось оппонент поленится забить эту строчку в гугл и подумает, что это отрывок из какой-то сурьёзной спецификации).

А ведь мог бы найти что-то подобное у того же Страуструпа, ведь это он впервые добавил возможность делать описания абы где, а не в начале блока. Выглядело бы солиднее, чем камент со stackoverflow в качестве пруфа.

Но мне не интересны цитаты даже таких мэтров, как Страуструп. У тебя своё мнение есть или ты только чужими мыслями пользоваться умеешь? Вот я своё мнение обосновал в другом каменте:

Вот чем удобнее описывать все переменные в начале блока, я могу объяснить: зайдя в блок, я сразу вижу все локальные переменные. Если я вижу где-то в середине или в конце блока использование переменной и хочу посмотреть её тип, я могу просто вернуться в начало блока и всё увижу.

И в C есть ООП, и в C++ есть ООП.

Это где же в си есть ооп? Или ты имеешь в виду, что описал переменную типа структуры в другой структуре - вот тебе и наследование? Создал поле-указатель на функцию - вот тебе и инкапсуляция с полиморфизмом в одном флаконе? Так, что ли? Так это понятно, что в конце концов всё преобразуется в машинный код. Но поддержка ооп на уровне языка - это когда им удобно пользоваться, а не наоборот.

Ты что, кретин?
Потому ты и вырос таким.
Ты и есть бред, парень, ты и есть бред.

На эти реплики пока мест закрываю глаза, понимая, что это ЛОР и что утёнок, воспитанный на ЛОРе, вполне может считать подобный тон нормой общения. Но впредь посты с подобными фразами буду игнорировать. Поэтому, если не хочешь писать в пустоту, - смени тон. Или, если по-другому говорить не умеешь, можешь вообще не отвечать, я переживу.

aureliano15 ★★
()
Ответ на: комментарий от BruteForce

использовать для них одну переменную i немного эффективнее

Ахаха. Найди лишнюю инструкцию: https://pastebin.com/aQ5Vd5Pa https://pastebin.com/ddAyuVUt

С чего мне искать лишние инструкции в каких-то ассемблерных листингах, полученных неизвестно из чего и неизвестно чем?

Создаём файл test_asm.cpp с таким содержимым:

int cnt1(void)
{
  int n=0;
  for(int i=0; i<3; ++i) n+=i;
  for(int i=0; i<3; ++i) n+=i;
  return n;
}                                                                                                                                                                                   
                                                                                                                                                                                    
int cnt2(void)                                                                                                                                                                      
{                                                                                                                                                                                   
  int n=0;                                                                                                                                                                          
  int i;                                                                                                                                                                            
  for(i=0; i<3; ++i) n+=i;                                                                                                                                                          
  for(i=0; i<3; ++i) n+=i;                                                                                                                                                          
  return n;                                                                                                                                                                         
}

Компилим его командой

g++ -S test_asm.cpp

На выходе получаем ассемблерный листинг test_asm.s с таким содержимым:

        .file   "test_asm.cpp"                                                                                                                                                      
        .text                                                                                                                                                                       
        .globl  _Z4cnt1v                                                                                                                                                            
        .type   _Z4cnt1v, @function                                                                                                                                                 
_Z4cnt1v:                                                                                                                                                                           
.LFB0:                                                                                                                                                                              
        .cfi_startproc                                                                                                                                                              
        pushq   %rbp                                                                                                                                                                
        .cfi_def_cfa_offset 16                                                                                                                                                      
        .cfi_offset 6, -16                                                                                                                                                          
        movq    %rsp, %rbp                                                                                                                                                          
        .cfi_def_cfa_register 6                                                                                                                                                     
        movl    $0, -4(%rbp)
        movl    $0, -8(%rbp)
        jmp     .L2
.L3:
        movl    -8(%rbp), %eax
        addl    %eax, -4(%rbp)
        addl    $1, -8(%rbp)
.L2:
        cmpl    $2, -8(%rbp)
        jle     .L3
        movl    $0, -12(%rbp)
        jmp     .L4
.L5:
        movl    -12(%rbp), %eax
        addl    %eax, -4(%rbp)
        addl    $1, -12(%rbp)
.L4:
        cmpl    $2, -12(%rbp)
        jle     .L5
        movl    -4(%rbp), %eax
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   _Z4cnt1v, .-_Z4cnt1v
        .globl  _Z4cnt2v
        .type   _Z4cnt2v, @function
_Z4cnt2v:
.LFB1:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movl    $0, -4(%rbp)
        movl    $0, -8(%rbp)
        jmp     .L8
.L9:
        movl    -8(%rbp), %eax
        addl    %eax, -4(%rbp)
        addl    $1, -8(%rbp)
.L8:
        cmpl    $2, -8(%rbp)
        jle     .L9
        movl    $0, -8(%rbp)
        jmp     .L10
.L11:
        movl    -8(%rbp), %eax
        addl    %eax, -4(%rbp)
        addl    $1, -8(%rbp)
.L10:
        cmpl    $2, -8(%rbp)
        jle     .L11
        movl    -4(%rbp), %eax
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE1:
        .size   _Z4cnt2v, .-_Z4cnt2v
        .ident  "GCC: (Debian 4.9.2-10) 4.9.2"
        .section        .note.GNU-stack,"",@progbits

Как видно из листинга, 1-ая функция резервирует 12 байт в стеке под локальные переменные, а 2-ая - только 8. Я не призываю отлавливать блох и считать каждый байт в стеке или каждый процессорный такт. Но покажи мне преимущества 2 переменных i перед одной? То, что мне надо в исходном коде лишний раз писать слово int? Да, это тоже ерунда. Мне плевать, я не собираюсь обращать внимания на такие мелочи, если взамен ты мне покажешь хоть одно серьёзное преимущество!

aureliano15 ★★
()
Ответ на: комментарий от RazrFalcon

что вместо одной переменной будут задействованы 2 + лишняя операция присвоения?

Экономия на спичках.

Вы не ответили на вопрос

Чем лучше

Я готов потратиться на спички, если увижу в этом хоть какой-то смысл.

При чём тут метки - не ясно. Их нету в C/C++.

Я не про goto, а про метки. Пример: https://rustbyexample.com/flow_control/loop/nested.html

Во-первых, по приведённой ссылке пример не на си/си++, а на rust. А во-вторых, и где там нет меток? Цитирую:

#![allow(unreachable_code)]

fn main() {
    'outer: loop {
        println!("Entered the outer loop");

        'inner: loop {
            println!("Entered the inner loop");

            // This would break only the inner loop
            //break;

            // This breaks the outer loop
            break 'outer;
        }

        println!("This point will never be reached");
    }

    println!("Exited the outer loop");
}

«inner:» и «outer:» и есть метки.

Это вы нас двоих в клинику предлагаете унести.

Только одного.

Странно, учитывая, что я говорил ровно то же, что и он. Ну да ладно.

Разговор о фичах C++, которых нет в С. [skip] Начинали про то, что C++ отличается от С только наличием ООП, а после предоставленных примеров скатили обсуждение во вкусовщину.

Нет, я начал с того, что

это просто мелкие плюшки плюсов, которые можно использовать, а можно и не использовать, но никак не должно. [skip] Главное различие между сями и крестами - в отсутствии в сях и в наличии в крестах ООП.

Т. е. с самого начала я говорил не о мелких, а только важных с моей точки зрения отличиях. И в первом же посте выразил эту мысль довольно ясно.

А в си какая типизация?

Слабая. Я попутал строгую и статическую.

С этим согласен. И это, на мой взгляд, главная плюшка си++, помимо ооп и шаблонов.

Открою тайну - в Java/C# живут без raii, но там есть ООП.

При чём тут ява и шарп? Мы говорим о плюшках си++, не относящихся к ооп. raii относится к ооп, поэтому в данном контексте не катит.

При том, что большая часть stl реализована с помощью шаблонных классов.

Связи ноль.

Я, вообще-то, говорю о реальном программировании, а не о вакуумно-сферическом. А на практике шаблоны в основном используются в stl и в boost. До появления stl сам Страуструп считал шаблоны мелкой, не очень нужной плюшкой, о чём прямо писал в своей книге.

aureliano15 ★★
()
Ответ на: комментарий от BruteForce

Правильно вот так:

int main()
{
    constexpr auto NUM_MAX{99};
    for (size_t i = 1; i <= NUM_MAX; ++i) {
        const auto sq_root = std::sqrt(static_cast<double>(i));
        std::cout << i << ' ' << sq_root << '\n';
    }
}



Зачем здесь size_t?

evilface ★★
()
Ответ на: комментарий от aureliano15

Странно, что ты поставил в конце '\n', а не std::endl, как рекомендует большинство руководств по си++. Впрочем, я не такой педант и придираться к разной ерунде не буду.

А не нужно верить руководствам. std::endl флашит поток. Тебе нужно флашить поток после каждого cout? Нет? Ну тогда это очевидный оверхед.

anonymous
()
Ответ на: комментарий от evilface

Посмею предположить, что size_t нужен, чтобы подчеркнуть беззнаковую природу счетчика. В данном случае это роли не играет, но лично я считаю полезным определять явный unsigned там, где signed не предусмотрен. На всяк пожарный.

anonymous
()
Ответ на: комментарий от aureliano15

auto

Это чтоб название типа в описании не писать? Очень нужная фича.

В C++ это _ОЧЕНЬ_ нужная фича. Чтобы это понять, надо немного пописать на крестах ;) Ну, а чтобы быть последовательным и придерживаться одного стиля многие суют auto везде, где могут. Впрочем, ничего плохого в этом не вижу.

anonymous
()
Ответ на: комментарий от anonymous

size_t нужен, чтобы подчеркнуть беззнаковую природу счетчика.

Для этого есть unsigned. А size_t нужен для индексирования.

aureliano15 ★★
()
Ответ на: комментарий от anonymous

auto

В C++ это _ОЧЕНЬ_ нужная фича.

А для чего? Я писал на крестах, но обходился без auto. И вообще предпочитаю строгую типизацию. А если что, в крестах есть шаблоны.

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

Погоди, так size_t какой-то особо хитрый тип данных, который вот так просто нельзя использовать в качестве счетчика? Надо же...

anonymous
()
Ответ на: комментарий от aureliano15

А для чего?
А если что, в крестах есть шаблоны.

Вот потому и нужно.

anonymous
()
Ответ на: комментарий от aureliano15

Дедушка, авто и шаблоны — ортогональные вещи.

template <class F> struct ArgType;

template <class R, class T>
struct ArgType<R (*)(T)> {
    typedef T argument_type;
};

struct CppFunction {
    static double call(double a, double b, double c) { return a * b * c; }
};

struct T1 {
    static double call(int a) { return static_cast<double>(a); }
};

template <typename Function, typename... T>
auto wrap(typename ArgType<decltype(&T::call)>::argument_type... args)
     -> decltype(Function::call(T::call(args)...))       {
    return Function::call(T::call(args)...);
}

auto& wrappedFunction = wrap<CppFunction, T1, T1, T1>>
Для строгой типизации есть хаскель.

fluorite ★★★★★
()
Последнее исправление: fluorite (всего исправлений: 2)
Ответ на: комментарий от anonymous

'\n' иногда флашит, чтобы этого избежать -

std::cout.sync_with_stdio(false)l

anonymous
()
Ответ на: комментарий от Virtuos86

strong это вам не strict, мани.

В русскоязычной литературе часто встречается некорректный перевод термина «strong typing» как «строгая типизация»; корректный вариант «сильная типизация» используется лишь при противопоставлении «слабой типизации». Следует иметь в виду, что использование термина «строгий» в отношении системы типов языка может вызвать путаницу со строгой семантикой вычислений языка (англ. strict evaluation).

anonymous
()
Ответ на: комментарий от anonymous

В качестве счётчика много что можно использовать, хоть double. size_t предназначен для хранения размеров структур, смещений и прочего и завязан на размер указателя в системе. Вам нужно, чтоб счётчик на x64 был 64битным?

khrundel ★★★★
()
Ответ на: комментарий от anonymous

Ну, как бы «беззнаковость» числа подчёркивается словом «unsigned». А здесь size_t, на мой взгляд, совершенно не к месту.

evilface ★★
()
Ответ на: комментарий от khrundel

c99 standard 6.5.3.4:

The value of the result is implementation-defined, and its type (an unsigned integer type) is size_t, defined in <stddef.h> (and other headers)

Вам нужно, чтоб счётчик на x64 был 64битным?

Мне нужен unsigned integer в тех местах, где signed не предусмотрен алгоритмом.

Оптимальный размер intger'a равен размеру регистра процессора.

anonymous
()
Ответ на: комментарий от anonymous

Оптимальный размер intger'a равен размеру регистра процессора.

Регистр eax в x64 никуда не делся. Более того, чтоб арифметическая операция работала и с его расширенной частью потребуется однобайтовый префикс. Также и в x64, и в aarch64 нет проблем с доступом к памяти, выравненному по 32 битами. Бездумное использование 64битных чисел может повредить векторизации. В общем нет, используйте int/unsigned, именно они традиционно самые удобные размеры для процессора, а size_t для размеров, смещений и индексов.

khrundel ★★★★
()
Ответ на: комментарий от khrundel

Бездумное использование 64битных чисел может повредить векторизации.

Когда нужна векторизация, тогда и стоит о ней думать.

В общем нет, используйте int/unsigned, именно они традиционно самые удобные размеры для процессора

4.2

а size_t для размеров, смещений и индексов

size_t для беззнаковых целых и это отражено в стандарте.

auto x = strlen(str);
for(auto i = 0; i < x; ++i) {
...

i - int

x - size_t

компилятор недоволен.

anonymous
()
Ответ на: комментарий от anonymous

В общем нет, используйте int/unsigned, именно они традиционно самые удобные размеры для процессора

4.2

Все сильно зависит от процессора. В большинстве случаев разницы нет или она несущественна.

anonymous
()
Ответ на: комментарий от anonymous

Когда нужна векторизация, тогда и стоит о ней думать.

Автоматическая векторизация затем и придумана, чтоб о ней не думать. Компилятор может подумать, если дурак-программист не использовал size_t там где не надо.

size_t для беззнаковых целых и это отражено в стандарте.

Хммм, значит strlen(), функция, вычисляющая размер строки, внезапно возвращает специальный тип, созданный для представления размера? И для индексирования внутри строки стандарт предлагает использовать специальный тип, который предназначен для индексации?

Всё это, наверняка для вас ново и удивительно, но я всё равно настаиваю, что size_t предназначен для размеров, смещений и индексов.

khrundel ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.