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

Является ли void() допустимым выражением C++?

Судя по всему, это тернарное выражение с void() в качестве одного аргумента компилируется:

void foo() {}

//...
a == b ? foo() : void();

Является ли void() допустимым выражением по стандарту или это просто компилятор? Если оно верно, то что это за выражение?

28.01.2020

  • Это просто кто-то пытается быть умным. if(a==b){ foo(); } четче и имеет тот же эффект. 28.01.2020
  • @CássioRenan вашу версию нельзя использовать в выражении. 28.01.2020
  • @M.M да, но я действительно не могу придумать никакого полезного способа использования этого в выражении, учитывая, что вы не можете создавать объекты типа void. (Хотя я буду первым, кто скажет, что то, что я не могу думать об одном, не означает, что оно не может существовать) 28.01.2020
  • Возможно, это может произойти в расширении пакета параметров или в каком-то метапрограммировании шаблона, где void происходит из типа шаблона, а это выражение является аргументом для вызова другой функции. 28.01.2020
  • @M.M, вы не можете передать void() в качестве аргумента. 29.01.2020
  • @CássioRenan: Возможное использование void(): с SFINAE: template <typename T> auto bar(T t) -> decltype(func(t), void()) (тип возвращаемого значения — void) Или для обработки злой перегрузки оператора запятой: (f1(t), void(), f2(t)). 29.01.2020
  • @ Jarod42 Я никогда не утверждал, что void() бесполезен. Я знаю, что это очень полезно в метапрограммировании (вот почему std::void_t так важно). Я рассуждаю конкретно о a==b?foo():void(). Если бы вы поместили это выражение, например, в decltype, то вам действительно не нужен тернарный оператор, поскольку ни логическое выражение не будет проверено, ни foo() фактически не будет вызвано. То же самое для обработки оператора запятой. 29.01.2020
  • @CássioRenan: Это будет decltype(a == b ? foo() : void()) против decltype(a==b, void(), foo(), void()) (первый короче, даже если я предпочитаю последний). 29.01.2020
  • Какой смысл столько раз отвечать на один и тот же вопрос, если у нас есть дублирующая система? 29.01.2020

Ответы:


1

void() является допустимым выражением и дает значение prvalue типа void. В C++ 20 это будет расширено за счет включения void{}. Соответствующий раздел для этого: [expr.type.conv]/2

Если инициализатор представляет собой одиночное выражение в скобках, выражение преобразования типа эквивалентно соответствующему выражению приведения. В противном случае, если тип — cv void, а инициализатор — () или {} (после расширения пакета, если есть), выражение представляет собой значение prvalue указанного типа, не выполняющее инициализацию. В противном случае выражение является значением prvalue указанного типа, объект результата которого инициализируется напрямую с помощью инициализатора. Если инициализатор представляет собой необязательный список-выражений в скобках, указанный тип не должен быть типом массива.

28.01.2020
  • Итак, void{} должен компилироваться, но не компилируется. Согласно этому должен. Но почему это не так? 28.01.2020
  • @NutCracker Это допустимо только в C++20. Еще не все компиляторы догнали. C++20 еще даже не доработан. 28.01.2020
  • @NutCracker Нет проблем. Это необходимое дополнение, чтобы попытаться сделать унифицированную инициализацию более единообразной. 28.01.2020

  • 2

    В дополнение к другим ответам, из здесь:

    void — тип с пустым набором значений. Это неполный тип, который не может быть завершен (следовательно, объекты типа void запрещены). Нет ни массивов пустоты, ни ссылок на пустоту. Однако указатели на void и функции, возвращающие тип void (процедуры на других языках), разрешены.

    Это означает, что вы можете инициализировать свой тип void любым значением a == b ? foo() : void(1) или a == b ? foo() : void(1111), но он ничего не выполнит и все равно будет успешно компилироваться.

    28.01.2020
    Новые материалы

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

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

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

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

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

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

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