I have the following code:
class MyClass
{
static constexpr bool foo() { return true; }
void bar() noexcept(foo()) { }
};
I would expect that since foo()
is a static constexpr
function, and since it's defined before bar
is declared, this would be perfectly acceptable.
However, g++
gives me the following error:
error: ‘static constexpr bool MyClass::foo()’ called in a constant expression
This is...less than helpful, since the ability to call a function in a constant expression is the entire point of constexpr
.
clang++
is a little more helpful. In addition to an error message stating that the argument to noexcept
must be a constant expression, it says:
note: undefined function 'foo' cannot be used in a constant expression
note: declared here
static constexpr bool foo() { return true; }
^
So...is this a two-pass-compilation problem? Is the issue that the compiler is attempting to declare all the member functions in the class before any of them are defined? (Note that outside of the context of a class, neither compiler throws an error.) This surprises me; intuitively, I don't see any reason for static constexpr
member functions not to be useable in any and all constant expressions, inside the class or out.
bar
isn't complete before thenoexcept
expression that uses it in your example, so there's no inconsistency. – Irradiancestatic constexpr
member functions be fully defined as soon as they are encountered, or something). – Irradianceauto
example in CWG 1255 illustrates one of the problems. – Webbedvoid bar() noexcept(noexcept(foo())); static constexpr bool foo();
(Note that declaringfoo
beforebar
is legal.) Also, theauto
example is not, in fact, a problem: there is no reasondecltype(f())
shouldn't be equivalent todecltype(42)
in that context. – Irradiancestatic const
==constexpr
, so you should useconstexpr bool foo() { return true; }
instead ofstatic constexpr bool foo() { return true; }
. – Corlisscorlyconstexpr
constructors), non-static
member functions are illegal. For literal types,static
and non-static
member functions are different in the typical way (non-static
member functions require a valid instance to call, and can access member data). – Irradianceconstexpr
impliesstatic
. – Irradiance