В чем разница между (типом) значением и типом (значением)?

В чем разница между

(type)value 

а также

 type(value) 

в C ++?

Нет никакой разницы; по стандарту (п. 5.2.3):

Спецификатор простого типа (7.1.5), за которым следует заключенный в скобки список выражений, строит значение указанного типа с учетом списка выражений. Если список выражений является одним выражением, выражение преобразования типа эквивалентно (в определенности и, если определено по смыслу), в соответствующее выражение (5.4).

Поскольку вопрос задает разницу между type(value) и (type)value , нет никакой разницы.

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

Если в списке выражений указано более одного значения, тип должен быть classом с соответствующим объявленным конструктором (8.5, 12.1), а выражение T (x1, x2, …) эквивалентно фактически объявлению T t (x1, x2, …); для некоторой изобретенной временной переменной t, результатом которой является значение t как rvalue.

Как указывал Трубадур, существуют определенные имена типов, для которых версия type(value) просто не будет компилироваться. Например:

 char *a = (char *)string; 

будет компилироваться, но:

 char *a = char *(string); 

не будет. Один и тот же тип с другим именем (например, созданный с помощью typedef ) может работать:

 typedef char *char_ptr; char *a = char_ptr(string); 

Нет никакой разницы; стандарт C ++ (выпуски 1998 и 2003 годов) ясно из этого момента. Попробуйте следующую программу, убедитесь, что вы используете совместимый компилятор, например, бесплатный просмотр по адресу http://comeaucomputing.com/tryitout/ .

 #include  #include  int main() { int('A'); (int) 'A'; // obvious (std::string) "abc"; // not so obvious unsigned(a_var) = 3; // see note below (long const&) a_var; // const or refs, which T(v) can't do return EXIT_SUCCESS; } 

Примечание: unsigned(a_var) отличается, но показывает один из способов, что точные жетоны могут означать что-то еще. Он объявляет переменную с именем a_var типа unsigned и не является литой. (Если вы знакомы с указателями на функции или массивы, подумайте о том, как вы должны использовать parens вокруг p в типе типа void (*pf)() или int (*pa)[42] .)

(Предупреждения производятся, поскольку эти утверждения не используют значение и в реальной программе, которая почти наверняка будет ошибкой, но все еще работает. У меня просто не было сердца, чтобы изменить ее после того, как все выстроилось в линию).

Нет никакой разницы, когда оба являются приведениями, но иногда «тип (значение)» не является произведением.

Вот пример из стандартного черновика N3242, раздел 8.2.1:

 struct S { S(int); }; void foo(double a) { S w( int(a) ); // function declaration S y( (int)a ); // object declaration } 

В этом случае «int (a)» не является актом, потому что «a» не является значением, это имя параметра, окруженное резервными скобками. В документе говорится

Неопределенность, возникающая из-за сходства между приведением в стиле функции и декларацией, упомянутой в 6.8, может также возникать в контексте декларации. В этом контексте выбор осуществляется между объявлением функции с избыточным набором круглых скобок вокруг имени параметра и объявлением объекта с использованием функции-стиля в качестве инициализатора. Так же как и для двусмысленностей, упомянутых в 6.8, резолюция состоит в том, чтобы рассмотреть любую конструкцию, которая может быть объявлением декларацией.

В c нет type (value) , тогда как в c / c ++ допустимы (type) value type (value) и (type) value .

Чтобы проиллюстрировать ваши варианты на C ++ (только один имеет проверку безопасности)

 #include using std::cout; using std::endl; int main(){ float smallf = 100.1; cout << (int)smallf << endl; // outputs 100 // c cast cout << int(smallf) << endl; // outputs 100 // c++ constructor = c cast cout << static_cast(smallf) << endl; // outputs 100 // cout << static_cast(smallf) << endl; // not allowed cout << reinterpret_cast(smallf) << endl; // outputs 1120416563 cout << boost::numeric_cast(smallf) << endl; // outputs 100 float bigf = 1.23e12; cout << (int)bigf << endl; // outputs -2147483648 cout << int(bigf) << endl; // outputs -2147483648 cout << static_cast(bigf) << endl; // outputs -2147483648 // cout << static_cast(bigf) << endl; // not allowed cout << reinterpret_cast(bigf) << endl; // outputs 1401893083 cout << boost::numeric_cast(bigf) << endl; // throws bad numeric conversion } 
  • В чем разница между «1L» и «1»?
  • Как разрешить «должен быть экземпляр строки, строка, заданная» до PHP 7?
  • Преобразование std :: __ cxx11 :: string в std :: string
  • Создание экземпляра Generic с переменной, содержащей тип
  • Почему Java-коллекции не могут напрямую хранить типы примитивов?
  • Как установить значение составного поля переменных с помощью динамического SQL
  • Давайте будем гением компьютера.