Создан ли компилятором конструктор constexpr по умолчанию? - PullRequest
0 голосов
/ 24 апреля 2018

Следующий код успешно компилируется с обоими clang ++ 3.8.0 и g ++ 7.2.0 (флаги компиляции -std=c++14 -Wall -Wextra -Werror -pedantic-errors):

struct Foo
{
    constexpr operator bool() const
    {
        return false;
    }
};


int main()
{
    constexpr bool b = Foo{};

    (void)b;
}

Соответствует ли такое поведение стандартного компилятора? Обратите внимание, что добавление любого члена (например, int i;) в класс Foo ничего не меняет .

Ответы [ 2 ]

0 голосов
/ 24 апреля 2018

Да, неявный конструктор является constexpr в этом случае. В общем случае это зависит от подобъектов.

[class.ctor]

Конструктор по умолчанию, который по умолчанию не определен как удаленный, неявно определяется при использовании odr (6.2) создать объект своего типа (4.5) или когда он явно задан по умолчанию после первого объявления. неявно определенный конструктор по умолчанию выполняет набор инициализаций класса, который будет выполнен написанным пользователем конструктором по умолчанию для этого класса без инициализации ctor (15.6.2) и пустого составного заявление. Если этот пользовательский конструктор по умолчанию будет неверно сформирован, программа будет некорректно сформирована. Если это Пользовательский конструктор по умолчанию будет удовлетворять требованиям конструктора constexpr (10.1.5), неявно определенный конструктор по умолчанию - constexpr . ... [snip]

Соответствующие требования конструктора constexpr:

[dcl.constexpr]

  • класс не должен иметь никаких виртуальных базовых классов;
  • для не делегирующего конструктора, каждый конструктор выбран для инициализации нестатических элементов данных и подобъекты базового класса должны быть конструктором constexpr;
0 голосов
/ 24 апреля 2018

Да, это так.Конструктор по умолчанию, который генерирует компилятор, и тривиальный конструктор

Foo() = default;

и позволяют писать constexpr bool b = Foo{};, предполагая, что все члены класса могут быть построены constexpr.Обратите внимание, что если бы вы написали

Foo(){}

, то constexpr будет , а не будет разрешено.(Важное различие между default и конструктором с пустым телом.)

...