问题
Look at this code:
struct NonConstexpr {
NonConstexpr() { }
};
template <typename T>
struct Bar {
NonConstexpr nonConstexpr;
constexpr Bar() { }
};
struct Foo {
Bar<void> bar;
constexpr Foo() { }
};
In this code, Foo
's constructor is tagged as constexpr
, but it cannot appear in a constant expression, as it actually fails to satisfy the requirements of this. You can read the details of this in my previous question.
My question is: can I detect somehow compile-time, that Foo
's constructor actually won't behave as constexpr
?
The reason I ask this, I'd like to detect that a global variable of Foo
will be statically initialized or not (I'd like to put a static_assert
on this, as my global Foo
object must be initialized statically).
Note, that the straightforward solution, to temporarily add constexpr
to the variable doesn't work, as my Foo
has a non-trivial destructor.
回答1:
If you are using Clang, use [[clang::require_constant_initialization]]
on the variable. Otherwise, I don't know of a way.
The committee is looking at standardizing this as a keyword.
回答2:
The only (current, toolchain-independent) way to prevent the compiler dropping the constexpr silently that I'm aware of, is to assign to a constexpr:
struct NonConstexpr {
NonConstexpr() { }
};
template <typename T>
struct Bar {
NonConstexpr nonConstexpr;
constexpr Bar() { }
};
struct Foo {
Bar<void> bar;
constexpr Foo() { }
};
int main()
{
constexpr auto f = Foo();
return 0;
}
... will fail to compile with constexpr constructor calls non-constexpr function "Bar<T>::Bar() [with T=void]"
来源:https://stackoverflow.com/questions/53632120/how-can-i-detect-that-a-constuctor-is-really-constexpr-so-i-can-utilize-static