It depends on how you use these constant expressions.
The ODR (one-definition rule) states that
(§3.2 / 2) [...] A variable whose name is displayed as a potentially evaluable expression is used by odr if it is not an object that satisfies the requirements for displaying in the constant expression (5.19) and lvalue to-rvalue (4.1) is immediately applied . [...]
( , .)
, odr, . , , , .
, :
int main() {
E e = GetE<float>::type;
return 0;
}
:
void f(const E &)
{ }
int main() {
f(GetE<float>::type);
return 0;
}
f (const), lvalue-to-rvalue , odr. , .
(. (. ), , , . , -O0 ( , ).)
, , struct-definition:
constexpr E GetE<float>::type;
constexpr E GetE<char>::type;
constexpr E GetE<int>::type;
.cpp( ), , .
, , .. constexpr ( ), :
template <class T> constexpr E GetE();
template <> constexpr E GetE<float>()
{ return TYPE_FLOAT; }
template <> constexpr E GetE<char>()
{ return TYPE_CHAR; }
template <> constexpr E GetE<int>()
{ return TYPE_INT; }
void f(const E &)
{ }
int main() {
E e = GetE<float>();
f(GetE<float>());
return 0;
}