I have this very simple function which won't compile.
constexpr void func()
{
}
The error I'm getting is:
error: invalid return type 'void
' ofconstexpr
function 'constexpr void func()
'constexpr void func()
In C++14, void
is a literal type [§3.9/10]:
A type is a literal type if it is:
- void; or
- a scalar type; or
- a reference type; or
- an array of literal type; or
- a class type (Clause 9) that has all of the following properties:
- it has a trivial destructor,
- it is an aggregate type (8.5.1) or has at least one
constexpr
constructor or constructor template that is not a copy or move constructor, and- all of its non-static data members and base classes are of non-volatile literal types.
Can someone explain why this is invalid?
The easiest way to check whether a function (e.g., foo ) is constexpr is to assign its return value to a constexpr as below: constexpr auto i = foo(); if the returned value is not constexpr compilation will fail.
It means that compiler can't guarantee that your if-constexpr is always compile-time, hence the error about it. If you place all your arguments as template auto parameters of your function then it should compile well.
The keyword constexpr was introduced in C++11 and improved in C++14. It means constant expression. Like const , it can be applied to variables: A compiler error is raised when any code attempts to modify the value. Unlike const , constexpr can also be applied to functions and class constructors.
A constexpr function is a function that can be invoked within a constant expression. A constexpr function must satisfy the following conditions: It is not virtual. Its return type is a literal type.
The proposal which made void
a literal type was n3652 Relaxing constraints on constexpr
functions. G++ decided to push this feature to version 5 (I was using 4.9.2):
G++ now supports C++14 extended constexpr.
constexpr int f (int i) { int j = 0; for (; i > 0; --i) ++j; return j; } constexpr int i = f(42); // i is 42
Clang has had this implemented since version 3.4.
It is valid indeed, but not yet supported in GCC. An example in the standard actually includes constexpr
functions returning void
- see [dcl.constexpr]/1:
constexpr void square(int &x); // OK: declaration
// [..]
constexpr void square(int &x) { // OK: definition
x *= x;
}
Example on Coliru using Clang, which is conforming here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With