http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47774
Summary: [C++0x] constexpr specifier on ctor not ignored when template instantiation causes ctor to not satify constexpr requirements Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: dev.li...@jessamine.co.uk The definition of b in the program below fails to compile due to the default constructor for its only member not being a valid constexpr. B itself does not claim to be a literal type or that instances of it should be usable as constants but g++ currently seems to enforce the constexpr nature of the ctor of X<T> even when T causes the definition to fail to meet the constexpr constructor requirements. 7.1.5 para 4 states: 6 If the instantiated template specialization of a constexpr function template or member function of a class template would fail to satisfy the requirements for a constexpr function or constexpr constructor, that specialization is not a constexpr function or constexpr constructor. [Note: if the function is a member function it will still be const as described below. Implementations are encouraged to issue a warning if a function is rendered not constexpr by a non-dependent construct. --end note] The program below demonstrates what I think to be non-compliance with this. It is a reduced case (I originally came across this when attempting to instantiate a std::array<std::pair<F,S>,N> where objects of either F or S were not usable as constants; pair's default constructor is specified as constexpr yielding the same problem). template <typename T> struct X { constexpr X() : t() {} T t; }; struct CanBeCompileTimeConstant { constexpr CanBeCompileTimeConstant() {} }; struct CannotBeCompileTimeConstant { CannotBeCompileTimeConstant() {} }; X<CanBeCompileTimeConstant> nonconstexpr1; X<CannotBeCompileTimeConstant> nonconstexpr2; constexpr X<CanBeCompileTimeConstant> constexpr1; //constexpr X<CannotBeCompileTimeConstant> constexpr2; // fails as expected struct A { X<CanBeCompileTimeConstant> mem; }; struct B { X<CannotBeCompileTimeConstant> mem; }; A a; B b; // fails unexpectedly: 'constexpr X<T>::X() [with T = CannotBeCompileTimeConstant]' is not 'constexpr'