Triggering lvalue-to-rvalue conversion of the inactive member of a union is not a constant expression. That is, given the union
:
template<class T, class U>
union A {
constexpr A(T t) : t_{t} {}
constexpr A(U u) : u_{u} {}
T t_;
U u_;
};
and the constexpr
function foo
:
template<class T, class U>
constexpr auto foo() {
A<T, U> a(T{});
return a.u_;
}
the following program:
int main() {
constexpr auto test = foo<int, double>();
return 0;
}
fails with the error message:
error: constexpr variable 'test' must be initialized by a
constant expression
constexpr auto test = foo<int, double>();
^ ~~~~~~~~~~~~~~~~~~
note: read of member 'u_' of union with active member 't_' is
not allowed in a constant expression
return a.u_;
^
note: in call to 'foo()'
constexpr auto test = foo<int, double>();
^
1 error generated.
Is there a workaround to achieve this behavior within constant expressions in C++14? reinterpret_cast
isn't allowed either.
Motivation: I'm trying to make google-test's floating-point comparison utility constexpr.