Это плохо сформировано, но диагностика не требуется. Проблема в том, что f()
в constexpr Value(const type_t& value): compile_time_bool(f())
может не отображаться в постоянном выражении для любого аргумента шаблона. Но учтите:
struct A{};
struct B{};
bool foo(A);
constexpr bool foo(B) { return {}; }
template<class T>
constexpr bool bar(T p) { return foo(p); }
Здесь constexpr
ность bar
зависит от аргумента шаблона. Поэтому:
constexpr A a{};
constexpr B b{};
//constexpr auto ba {bar(a)}; // error
constexpr auto ba {bar(b)}; // fine
auto ba2 {bar(a)}; // fine
Шаблон функции помечаются как constexpr
может производить constexpr
и нефизических constexpr
специализаций, в зависимости от аргументов шаблона.
Это, вероятно, трудно или невозможно проверить, если шаблон функции не constexpr
для любого набора аргументов шаблона (в случае ФП, это может быть возможным, чтобы видеть, что, как f()
однозначно относится к Value::f
). Поэтому диагностика не требуется.
Соответствующий параграф [dcl.constexpr]/6:
Если экземпляр шаблона специализация constexpr
функции шаблона или члена функции шаблона класса будет не в состоянии удовлетворить требования, предъявляемые к constexpr
или constexpr
конструктор, эта специализация не является функцией constexpr
или constexpr
конструктором. [Примечание: Если функция является функцией-членом, она все равно будет const, как описано ниже. - конец примечания] Если никакая специализация шаблона не будет даст функцию constexpr
или constexpr
конструктор, программа плохо сформирована; не требуется диагностика.
N.B. объект const
будет поднят на C++ 1y, поэтому лучше использовать функции элемента-метки (а не ctors, очевидно) как как constexpr
, так и const
.
Фактически, программа имеет UB. Но как только вы создаете экземпляр ctor в контексте, который требует постоянного выражения, ваш компилятор должен жаловаться - как и clang ++ 3.4
Оба компилятора, похоже, принимают вашу программу, если вы используете ctor в контексте, где постоянное выражение не требуется. Я бы сказал, что это расширение, но в этом случае так же сложно выпустить предупреждение («расширение используется, непереносимый код»), чтобы диагностировать программу, в первую очередь, плохо сформировалось.
Он также работает с clang 3.3. – razeh
Кажется, что это может быть ошибкой в том, что шаблоны не создаются, пока они не потребуются. Если вы используете класс в 'static_assert()', он терпит неудачу. Я полагаю, вы использовали его в контексте выполнения. Однако я думаю, что он должен был пожаловаться на 'constexpr', потому что этот конструктор никогда не является постоянным выражением. – mpark
@mpark Черт, я действительно надеялся, что могу использовать std :: vector как список объектов времени компиляции ... есть ли что-нибудь, что делает это? – NmdMystery