Представляет ли конструктор по умолчанию ноль для универсальных типов в C ++ - PullRequest
2 голосов
/ 24 мая 2019

Предположим, что есть функция, и она работает

template <typename T> 
Range<T> IRange(T lower, T upper){
  ....
}

Итак

IRange(0,5)

создаст Range со значениями [0,1,2,3,4]. Точное поведение класса Range не важно.

Однако теперь я хочу вспомогательную функцию

template <typename T> 
Range<T>
Repeat(T t){
    return IRange(T(), t);
}

так что

Repeat(5)

также выдаст Range со значениями [0,1,2,3,4].

Вопрос:

Является ли использование T() для получения значения ноль в общем приемлемым?

Я так думаю, но что-то меня раздражает, что это может быть неправильно.

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

Ответы [ 2 ]

3 голосов
/ 24 мая 2019

Если T равно int, то

int i = int(); 

value-initializes i, что для int означает, что оно инициализируется нулем, так что оно содержит значение 0. (Обратите внимание, что этот синтаксис не требует присутствия конструктора для встроенных типов, таких как int .)

Как правило, T() - это инициализация значения, и значение зависит от того, что T определено ниже:

Эффекты инициализации значения:

1) если T является типом класса по крайней мере с одним предоставленным пользователем конструктором любого вида, вызывается конструктор по умолчанию; (до C ++ 11)
1) если T является типом класса без конструктора по умолчанию или с предоставленным пользователем или удаленным конструктором по умолчанию, объект инициализируется по умолчанию; (начиная с C ++ 11)
2) если T является типом класса, не являющимся объединением, без каких-либо предоставленных пользователем конструкторов, каждый элемент нестатических данных и компонент базового класса T инициализируется значением; (до C ++ 11)
2) если T является типом класса с конструктором по умолчанию, который не предоставлен и не удален пользователем (то есть это может быть класс с неявно определенным или дефолтным конструктором по умолчанию), объект инициализируется нулями и затем инициализируется по умолчанию, если у него есть нетривиальный конструктор по умолчанию; (начиная с C ++ 11)
3) если T является типом массива, каждый элемент массива инициализируется значением; 4) в противном случае объект инициализируется нулями.

0 голосов
/ 24 мая 2019

Представляет ли конструктор по умолчанию ноль для универсальных типов в C ++

Нет, это явно не так, например. для std::vector<char>().

Однако вам нужно мыслить в терминах ограничений или, что то же самое, концепций. Для каких концептуальных T типов имеют смысл ваши функции IRange и Repeat? Из того, что вы написали, становится ясно, что типы должны быть концептуально числовыми.

C ++ еще не имеет формальных определений таких понятий (C ++ 20 получит некоторые), но определение специального понятия для числовых типов является относительно простым (считаются важными тонкостями) основывая их на том, что делает int.

Для вашей цели это точно соответствует ответу P.W: для числовых типов T() является хорошим кандидатом для идентификации при добавлении (он же 0). Эквивалентно, вы можете использовать «равномерную» инициализацию 1 , T{}, и некоторые люди предпочитают это особенно для универсального кода.


1 К сожалению «равномерная инициализация» не , но вы можете игнорировать это в вашем случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...