问题
#include <algorithm>
struct S
{
static constexpr int X = 10;
};
int main()
{
return std::min(S::X, 0);
};
If std::min
expects a const int&
, the compiler very likely would like to have the S::X
also defined somewhere, i.e. the storage of S::X
must exists.
See here or here.
Is there a way to force the compiler to evaluate my constexpr
at compile time?
The reason is:
Initially, we had a problem in early initialization of static variables in the init priority. There was some struct Type<int> { static int max; };
, and some global static int x = Type<int>::max;
, and some other early code other_init
used that x
. When we updated GCC, suddenly we had x == 0
in other_init
.
We thought that we could avoid the problem by using constexpr
, so that it would always evaluate it at compile time.
The only other way would be to use struct Type<int> { static constexpr int max(); };
instead, i.e. letting it be a function.
回答1:
The constexpr
is evaluated at compile time. Your problem is
due to the fact that std::min
is not a constexpr
, so
regardless of its input, the results are not a const expression
(and in particular, if you initialize a variable with static
lifetime using std::min
, it is dynamic initialization).
The simplest solution is probably to define your own min
,
something along the lines of:
template <typename T>
constexpr T staticMin( T a, T b )
{
return a > b ? b : a;
}
This should result in full evaluation at compile time, and static initialization.
回答2:
For types that are allowed to exist as template value parameters, you can introduce a data structure like this:
template <typename T, T K>
struct force
{
static constexpr T value = K;
};
Usage:
force<int, std::min(S::X, 0)>::value
来源:https://stackoverflow.com/questions/24322386/force-constexpr-to-be-evaluated-at-compile-time