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 fromcommon_type<Baz, Foo, Bar>. Either might compile, the other might not. While this is clear from the waycommon_typeis 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_typewill actually compile?is_convertibleis not enough ascommon_typemight 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_typewhich is tedious. Is there a better solution?
For reference see §20.9.7.6 Table 57 in N3242.
std::common_typewas introduced for use withstd::duration— if you add astd::duration<int>and astd::duration<short>then the result should bestd::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_typeis 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_typeis not magic — it follows the rules of?:. Iftrue?a:bwill compile,std::common_type<decltype(a),decltype(b)>::typewill give you the type of the result.