10

Does the c++11 standard say anything about templated unions? (I can't find anything in http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf, but I haven't read it that carefully.)

I have

template<typename T>
union u {
  T a;
  char b;
};

template<typename T>
u<T> make_u(T t) {
  return { .a = t };
}

int main() {
  return make_u<int>(1).a;
}

This code causes icpc -std=c++11 to say error: a designator into a template-dependent type is not allowed, g++ -std=c++0x to say error: expected primary-expression before ‘.’ token, and g++ -std=c++11 (version 4.8.0 (experimental)) to say internal compiler error: in lookup_field_1, at cp/search.c:387. I can get around this by replacing { .a = t } with t. However, I could not do this for fields which are not the first member of the union. Is there a way to pick some member other than the first one in a templated union, where the relevant member is template-dependent? (I could, of course, declare a union on the stack, and set the member equal to the value I want. But I could not do this in an initializer list or in a constexpr function.)

timrau
  • 22,578
  • 4
  • 51
  • 64
Jason Gross
  • 5,928
  • 1
  • 26
  • 53

1 Answers1

13

The { .a = t } syntax is a non-standard GNU extension, so its interaction with other C++ features is outside the scope of the C++ standard.

Solution: write standard C++:

u<T> make_u(T t) {
  u<T> r;
  r.a = t;
  return r;
}

EDIT: AFAIK, in C++11, you can give your union a constructor (a constexpr if you like) that does the initialization you need. Example: http://ideone.com/s4GHjU

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220