Nano Hash - криптовалюты, майнинг, программирование

Возвращение пустоты?

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

#include <iostream>

template <class T>
struct Test
{
    static constexpr T f() {return T();} 
};

int main()
{
    Test<void> test;
    test.f(); // Why not an error?
    return 0;
}

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


  • Ну, я знаю, что тебе разрешено иметь, скажем, void foo() {} void bar() {return foo();}. Я не уверен в этом. 09.12.2013
  • О чем конкретно ваш вопрос? О возвращении void (которое, кстати, всегда было законным в C++)? Или про constexpr void комбинацию? 09.12.2013
  • Может быть, вам следует объяснить, в чем, по вашему мнению, должна быть ошибка? 10.12.2013

Ответы:


1

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

Выражение T(), где T – это спецификатор простого типа или спецификатор имени типа для полного типа объекта, не являющегося массивом, или типа void (возможно, с указанием cv), создает значение prvalue указанного типа, значение которого является результатом инициализации значения (8.5) объекта типа T; для случая void() инициализация не выполняется.[...]

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

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

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

и включает в себя этот пункт:

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

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

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

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

Тип является буквальным типом, если он:

и включает:

- пустота; или

09.12.2013

2

Полную информацию см. в ответе @Shafik Yaghmour.

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

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

  • [...]

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

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

09.12.2013
  • литеральный тип определен в 3.9/10; void не является буквальным типом в C++11. Однако в C++14 (N3797) void включено в литеральные типы. Таким образом, код ОП будет соответствовать С++ 14. 09.12.2013
  • @Casey Также я думаю, что пункт 6 7.1.5 позволяет это сделать в С++ 11. 09.12.2013
  • @ShafikYaghmour Ааа, согласен. Интересно: этот код специализируется на функциях-членах не constexpr, но const в C++11 или функциях-членах constexpr и не const в C++14! 09.12.2013
  • @Casey Это было бы правильно, если бы объявление было для функции-члена, отличной от static, но OP имеет член static, поэтому в любом случае он не будет const. Пожалуйста, обратите внимание, идиот! 09.12.2013

  • 3

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

    void f() { return void(); }
    

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

    09.12.2013
  • Я почти уверен, что это разрешено в C++ 5.2.3(2), хотя IANALL. 09.12.2013
  • Это разрешено компилятором, но на самом деле бесполезно, так как не имеет никакого значения. 09.12.2013
  • Это не главное, когда речь идет о стандарте языка. 09.12.2013
  • @user3084096 user3084096 это может быть полезно в качестве параметризованного типа в шаблоне, возвращающего сконструированный элемент по умолчанию. Это может избежать особых случаев. 10.12.2013
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..


    © 2024 nano-hash.ru, Nano Hash - криптовалюты, майнинг, программирование