Возrotation пустоты?

Я не понимаю, почему этот код компилируется без ошибок:

#include  template  struct Test { static constexpr T f() {return T();} }; int main() { Test test; test.f(); // Why not an error? return 0; } 

Это нормально в соответствии со стандартом, или это толерантность компилятора?

Это выглядит действительным по проекту стандарта C ++ 11 , если мы посмотрим на раздел 5.2.3 Явное преобразование типа (функциональная нотация) в абзаце 2 говорит ( акцент мой ):

Выражение T () , где T является спецификатором простого типа или спецификатором имени для типа объекта без массива или (возможно, cv-qualified) типа void , создает prvalue указанного типа, значение которого таково: созданный путем инициализации значения (8.5) объекта типа T; никакая инициализация не выполняется для случая void (). […]

формулировка довольно похожа на pre C ++ 11 .

Это нормально в constexpr, хотя в разделе 7.1.5 параграфе 3 говорится:

Определение функции constexpr должно удовлетворять следующим ограничениям:

и включает эту пулю:

его тип возврата должен быть буквальным;

и void не является буквальным в C ++ 11 в соответствии с разделом 3.9 параграфа 10 , но если мы посмотрим на пункт 6, он дает исключение, которое подходит для этого случая, в нем говорится:

Если специфицированная шаблонная специализация шаблона функции constexpr или функции-члена шаблона classа не будет удовлетворять требованиям для функции constexpr или конструктора constexpr, эта специализация не является конструктор-конструктором или конструктором constexpr. [Примечание. Если функция является функцией-членом, она все равно будет const, как описано ниже. -End note] Если никакая специализация шаблона не даст функции constexpr или constexpr, программа будет плохо сформирована; не требуется диагностика .

Как заметил Кейси в проекте стандарта C ++ 14, void является буквальным , это раздел 3.9 параграфе 10 говорится:

Тип – это буквальный тип, если он:

и включает:

– void; или

См. Ответ @Shafik Yaghmour для получения полной информации.

Следующий абзац запрещает это для не-шаблонов (7.1.5 (3)):

Определение функции constexpr должно удовлетворять следующим ограничениям:

  • […]

  • его возвращаемый тип должен быть буквальным типом или ссылкой на буквенный тип

Чтобы уточнить, буквальный тип определен в 3.9 (10) как скалярный тип или состав объектов литерала типа в массиве или структуре. void не является скалярным типом по 3,9 (9).

Ваша функция возвращает значение void() , вы не возвращаетесь из функции void как таковой. Вы возвращаете значение NULL . То, что вы делаете, эквивалентно этому:

 void f() { return void(); } 

Это возвращает значение void, единственное значение void. вы не можете вернуть ничего из функции void, потому что это будет другой тип.

  • Являются ли шаблоны C ++ просто маскируемыми?
  • Можно ли эмулировать шаблон ?
  • проверьте, существует ли элемент с помощью enable_if
  • std :: enable_if: параметр vs template
  • Инъекция зависимостей против заводского шаблона
  • SFINAE работает в обратном типе, но не как параметр шаблона
  • какова процедура частичного заказа в выводе шаблона
  • Виртуальный метод шаблона C ++
  • Проверьте, имеет ли class функцию-член определенной подписи
  • Разница между экземпляром и специализацией в шаблонах c ++
  • Bash Templating: Как создать файлы конфигурации из шаблонов с Bash?
  • Interesting Posts

    В чем разница между =>, () => и Unit =>

    Как получить сертификат отпечатка SHA-1 в Android Studio для режима отладки?

    Как передать аргументы командной строки, когда source () R-файл

    В каком дистрибутиве Linux есть самые современные пакеты?

    Фрагмент в ViewPager с использованием FragmentPagerAdapter пуст во второй раз

    Повысить накладные расходы на C ++

    Как вручную развернуть специальную переменную (например: ~ тильда) в bash

    Имеет ли C # свойства расширения?

    Как изменить FileZilla, чтобы View / Edit открывал .html в Notepad ++, а не Firefox

    onClick внутри fragmentа, вызванного активностью

    Уведомление о восстановлении задачи, а не конкретной деятельности?

    Bash Templating: Как создать файлы конфигурации из шаблонов с Bash?

    MVVM Light: добавление EventToCommand в XAML без смешивания, более простой способ или fragment?

    Балансировка нагрузки с несколькими шлюзами

    Сколько раз мы можем на низком уровне форматировать диск, не повредив его?

    Давайте будем гением компьютера.