Капитан Педантик спешит на помощь!
Если вы пишете
int(value)
Это то, что известно как явное преобразование типов и регулируется 5.2.3. Точная формулировка говорит о том, что
Спецификатор простого типа (7.1.5), за которым следует заключенный в скобки список-выражений, создает значение указанного типа с учетом списка выражений. Если список выражений представляет собой одно выражение, выражение преобразования типа эквивалентно (по определению и, если оно определено по смыслу) соответствующему выражению приведения (5.4)
(выделено мной). Итак, это означает, что
int(value)
а также
(int)value
полностью идентичны друг другу. Вам решать, какой из них вам легче писать.
Что касается вашего второго вопроса, в примере, который вы привели с шаблонами и массивом, я полагаю, что вы хотели написать что-то вроде этого.
template <typename T, size_t N>
size_t (T (&)[N]) {
return N;
}
Здесь N
, так же как и T
, является параметром шаблона, который позволяет вам передавать любой массив, который вы хотите, при этом компилятор заполняет N
количеством элементов в массиве. На случай, если это сбивает с толку (что такое T (&)[N]
?), это потому, что эта функция принимает параметр типа T (&)[N]
. Чтобы упростить чтение, давайте дадим этому параметру имя, как показано здесь:
template <typename T, size_t N>
size_t (T (&array)[N]) {
return N;
}
Я думаю, что это делает это немного легче читать. Но что означает это заявление?
T (&array)[N]
Это объявляет переменную с именем array
, которая является ссылкой на массив из T
s ровно N
элементов. Вы действительно можете объявлять ссылки на массивы точно так же, как вы можете объявлять указатели на массивы. Это не очень распространено на практике, но в этой конкретной идиоме шаблона это отличный способ заставить компилятор сделать вывод о размере массива для вас, поскольку он пытается сопоставить массив с аргументом шаблона.
Причина для круглых скобок в этом случае заключается в том, что если вы пишете
T& array[N]
Компилятор проанализирует это как «переменную с именем array
, которая представляет собой массив из N
объектов, каждый из которых является T&
. Однако спецификация C++ специально запрещает массивы ссылок, и это было бы недопустимо. Круглые скобки явно устраняют неоднозначность. аналогично указателям на функции - вы пишете
void (*functionPointer)()
вместо
void *functionPointer()
Чтобы компилятор понял, что *
означает, что functionPointer
является указателем, а не функцией, которая возвращает void *
.
Что касается того, как компилятор определяет, когда обрабатывать круглые скобки тем или иным образом, правила довольно сложны, и на самом деле есть несколько обстоятельств, при которых компилятор не будет анализировать ваше выражение предполагаемым образом. Одним из таких случаев является то, что в просторечии называется «наиболее неприятным синтаксическим анализом», когда компилятор обрабатывает то, что выглядит как конструкция объекта, как прототип функции. Например, этот код:
vector<int> v();
Не создает vector<int>
с именем v
, инициализированным с помощью конструктора по умолчанию. Вместо этого он рассматривает это как прототип функции с именем v
, которая не принимает аргументов и выдает vector<int>
! Однако, если бы вы написали
vector<int> v(10);
Тогда компилятор может однозначно сделать вывод, что это объявление vector<int>
, передающее 10
в качестве аргумента конструктора, потому что его никак нельзя рассматривать как прототип функции. 6.8 и 8.2 спецификации обрабатывают эти случаи, говоря, что все, что можно рассматривать как объявление, будет таковым, и все, что можно рассматривать как прототип функции, также будет им.
Скобки в контексте массива (то есть T (&array)[N]
) обрабатываются другой частью логики, потому что в контексте, в котором вы объявляете переменную или определяете параметр, тип которого требует явных круглых скобок, не может быть двусмысленность в отношении вашего намерения, потому что из контекста ясно, что вы называете тип, чтобы объявить переменную.
Обобщить -
- Слепки формы
T(value)
и (T)value
идентичны.
- Круглые скобки в
T (&array)[N]
предназначены для предотвращения привязки компилятором &
к T
вместо array
, как предполагалось.
- Конкретное использование круглых скобок обычно выводится из контекста, хотя некоторые проблемы могут возникать между объявлениями переменных и прототипами функций.
Надеюсь это поможет!
person
templatetypedef
schedule
19.02.2011
<
и>
не являются скобками. - person Rafe Kettler   schedule 19.02.2011