Workaround for converting the lvalue-to-value of an inactive member of a union within sparse constant expressions

Starting the lvalue-to-value conversion of an inactive member of a union is not a constant expression. That is, using 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 constexprfunction foo:

template<class T, class U>
constexpr auto foo() {
  A<T, U> a(T{});
  return a.u_;
}

following program:

int main() {
  constexpr auto test = foo<int, double>();
  return 0;
}

with 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 way around this behavior in constant expressions in C ++ 14? reinterpret_castalso not allowed.

Motivation: I'm trying to make a google-test constexpr floating point comparison utility.

+4
source share
1 answer

, ++ 14. ; , , undefined .

, , :

union U { int *p; size_t n; };
int a;
constexpr U u = { &a };
static_assert(u.n != 0x400e158, "'a' is at my favourite address");

, a .

+4

All Articles