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: [email protected]
ReportedBy: [email protected]
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'