В аргументе decltype
ожидается выражение.Единственный способ интерпретировать CLS()
как выражение - это проанализировать его как созданный по умолчанию объект типа CLS
.
Однако в CLS obj2(CLS())
(который, кстати, работает аналогично)в C ++ 03) существует два возможных анализа: один как объявление функции и один как определение объекта.В качестве объявления функции внешние скобки образуют список параметров, и ожидается, что содержимое будет указывать параметр (или список из них), давая типы и необязательные имена.В этом разборе CLS () интерпретируется как тип функции.
Другой допустимый синтаксический анализ - это определение объекта.Для этого анализа, конечно, в скобках должно быть выражение (или их список), дающее интерпретацию CLS()
как объекта по умолчанию типа CLS
.
Теперь в C ++Существует правило, что если что-то может быть проанализировано как объявление, так и как определение, оно будет проанализировано как объявление.То есть в этом случае будет использоваться первое толкование.
Это, конечно, вызывает вопрос , почему первое толкование выбрано, когда мы явно ожидаем второе здесь.И ответ таков: в противном случае это нарушит совместимость с C (а в некоторых случаях даже наши ожидания).Например, посмотрите на следующую строку:
int f();
Теперь вы согласитесь, что это объявляет функцию без аргументов и возвращающую int
, верно?Но это также может быть проанализировано как определение инициализированной по умолчанию переменной типа int
.Благодаря вышеупомянутому правилу, оно действительно объявляет функцию, возвращающую int
.
Правило, которое всегда дает результат, который, как можно ожидать, будет в лучшем случае сложным, но, скорее всего, невозможным.
Обратите внимание, что в C ++ 03 простым способом избежать этого для автоматических переменных было бы префикс определения с auto
: поскольку объявления функций никогда не начинаются с auto
, это заставило бы компилятор интерпретироватьэто как определение переменной.Так как старое значение auto
было удалено в C ++ 11, это больше не работает (и для неавтоматических переменных это никогда не работало в любом случае).