Приведение в стиле конструктора в параметрах вызова функции

Я не понимаю, почему следующий код не компилируется при использовании приведения типа конструктора:

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), но это не отвечает на вопрос;)

19

Решение

[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 В комментариях ниже отмечается, что разрешение этого было бы несовместимо с синтаксисом вызова функции, поскольку в именах функций не должно быть пробелов.

16

Другие решения


По вопросам рекламы [email protected]