Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Templated unions in c++11

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.)

like image 670
Jason Gross Avatar asked Nov 17 '12 16:11

Jason Gross


People also ask

What are union types in C++?

Purpose of Unions in C/ C++ Union is a user-defined datatype. All the members of union share same memory location. Size of union is decided by the size of largest member of union. If you want to use same memory location for two or more members, union is the best for that. Unions are similar to structures.

How a union is declared in C?

Syntax for declaring a union is same as that of declaring a structure except the keyword struct. Note : Size of the union is the the size of its largest field because sufficient number of bytes must be reserved to store the largest sized field. To access the fields of a union, use dot(.)

Can constructors be templated?

As long as you are satisfied with automatic type inference, you can use a template constructor (of a non-template class). @updogliu: Absolutely.

Can union have static members?

In C++ union can contain static members which, as in the case of classes, belong to a class and therefore are common to all objects.


1 Answers

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

like image 152
Yakov Galka Avatar answered Oct 18 '22 22:10

Yakov Galka