Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of std::common_type?

Tags:

I started looking at std::common_type and am not exactly sure about its purpose and its functionality. A few things still strike me as odd:

  • Order of arguments is important: common_type<Foo, Bar, Baz> might be different from common_type<Baz, Foo, Bar>. Either might compile, the other might not. While this is clear from the way common_type is defined, it feels strange and unintuitive. Is this for lack of a universal solution or intended?
  • Instantiation can result in a compiler error instead of something I can handle. How to check if common_type will actually compile? is_convertible is not enough as common_type might be specialized?
  • There is still no way to figure out the common type in a situation like this:

    struct Baz; struct Bar { int m; }; struct Foo { int m; };  struct Baz { Baz(const Bar&); Baz(const Foo&); }; 

    The recommended solution would be to specialize common_type which is tedious. Is there a better solution?

For reference see §20.9.7.6 Table 57 in N3242.

like image 331
pmr Avatar asked Jun 28 '11 08:06

pmr


1 Answers

std::common_type was introduced for use with std::duration --- if you add a std::duration<int> and a std::duration<short> then the result should be std::duration<int>. Rather than specifying an endless stream of allowed pairings, the decision was made to delegate to a separate template which found the result using the core language rules applicable to the ?: arithmetic-if operator.

People then saw that this template might be generally useful, and it was added as std::common_type, and extended to handle an arbitrary number of types. In the C++0x library it is only used for pairs of types though.

You should be able to use the new SFINAE rules to detect whether or not some instantiation of std::common_type is valid. I haven't tried though. In most cases if there isn't a "common type" then there isn't anything meaningful you can do anyway, so a compile error is reasonable.

std::common_type is not magic --- it follows the rules of ?:. If true?a:b will compile, std::common_type<decltype(a),decltype(b)>::type will give you the type of the result.

like image 148
Anthony Williams Avatar answered Sep 19 '22 15:09

Anthony Williams