Reputation: 8527
In the following piece of C++11 code, the function get
is constexpr
but it tries to construct an instance via the non-constexpr
constructor.
template <typename T>
struct S
{
S() {}
static constexpr S get() { return S(); }
};
int main()
{
// S<int> s1;
// auto s2 = s1.get();
}
While this code compiles with GCC, it fails with the compiler we use at work with the message
constexpr function return is non-constant.
We started a discussion whether the compiler is allowed to issue an error in
this case. I think that the compiler has to accept the code. Otherwise I do
not see how std::time_point
could work in C++11 because its constructor is
constexpr
only since C++14.
So is this a quality-of-implementation thing or does the standard say
something about uninstantiated templates w.r.t constexpr
?
Further, would it change anything if the code in the comments were
activated (i.e. invoking a constexpr
function on a non-constexpr
object)?
Upvotes: 1
Views: 167
Reputation: 158469
This line is fine:
S<int> s1;
but the following definition of get
is ill-formed:
static constexpr S get() { return S(); }
since it does not return a literal type since S
does not have a constexpr constructor.
From the draft C++11 standard section 7.1.5
The constexpr specifier [dcl.constexpr]:
The definition of a constexpr function shall satisfy the following constraints:
- its return type shall be a literal type;
and later on the section it says (emphasis mine):
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. —end note ] If no specialization of the template would yield a constexpr function or constexpr constructor, the program is ill-formed; no diagnostic required.
Note in the non-template case both gcc and clang generate an error since the return type is not a literal see it live.
Upvotes: 2