Я не понимаю, почему следующий код не компилируется при использовании приведения типа конструктора:
template<typename T> void foo(const T& t){}
int main(){
foo(unsigned char(0));
}
Ошибки:
error: expected primary-expression before ‘unsigned’
для GCC.error: expected '(' for function-style cast or type construction
для лязгаОднако эти три синтаксиса верны:
template<typename T> void foo(const T& t){}
int main(){
// c-style cast
foo((unsigned char)0);
// without unsigned
foo(char(0));
// aliased unsigned char
typedef unsigned char uchar;
foo(uchar(0));
}
Таким образом, пространство в типе, очевидно, здесь виновато.
Я думал, что это может быть как-то связано с нашим старым другом самый неприятный разбор, поэтому я попробовал единый синтаксис инициализации, который должен избавиться от такого рода неясностей, но не повезло
template<typename T> void foo(const T& t){}
int main(){
foo(unsigned char{0});
}
Но до сих пор:
error: expected primary-expression before ‘unsigned’
для GCC.error: expected '(' for function-style cast or type construction
для лязгаИтак, мой вопрос: почему нельзя использовать тип, содержащий пробел, в приведениях в стиле функции? Это не выглядит двусмысленным для меня.
нотаЯ знаю, что могу написать foo<unsigned char>(0)
, но это не отвечает на вопрос;)
[C++11: 5.2.3/1]:
простой тип спецификатор (7.1.6.2) или имяТипа спецификатор (14.6) с последующим в скобках список_выражений создает значение указанного типа с учетом списка выражений. [..]
Изучая грамматику, мы видим, что единственный способ получить unsigned char
от простой тип спецификатор производство путем объединения двух из них.
В качестве доказательства опровержения слухов о том, что таблица 10 утверждает обратное, которое я, возможно, сам начал некоторое время назад (: P), заголовок таблицы говорит «спецификатор (ы)» (обратите внимание на необязательное множественное число) и ссылается на проход:
[C++11: 5.2.3/2]:
[..] В таблице 10 приведены действительные комбинации из простой типа спецификаторы и типы, которые они указывают. (акцент мой)
Теперь, объединяя простой типа спецификаторы допускается в некоторых случаях:
[C++11: 7.1.6.2/3]:
Когда несколько простой типа спецификаторы разрешены, они могут свободно смешиваться с другими Децл-спецификаторы в любом порядке. [..]
… но нет никаких признаков того, что это имеет место с функциональной нотацией, которая ясно заявляет « простой тип спецификатор» — единственное число.
Поэтому GCC правильно, а Visual Studio неправильно.
Что касается Зачем это тот случай … ну, я не знаю. Я подозреваю, что мы могли бы придумать какой-то неоднозначный крайний случай, но Casey В комментариях ниже отмечается, что разрешение этого было бы несовместимо с синтаксисом вызова функции, поскольку в именах функций не должно быть пробелов.