我很困惑:在使用std::common_type
升级到GCC 6(RC1)之前,某些模板代码在失败之前有效。我试过clang,那也失败了...所以我一定做错了什么!
代码相当于:
#include <type_traits>
#include <typeinfo>
using namespace std;
// common_type of two const type_info& is ok (compiles ok)
common_type<const type_info&, const type_info&>::type func1();
// common_type of three type_info& is bad...(fails to compile)
common_type<const type_info&, const type_info&, const type_info&>::type func2();
// common_type of two const int& is ok
common_type<const int&, const int&>::type func3();
// common_type of three const int& is ok too!
common_type<const int&, const int&, const int&>::type func4();
具有类型common_type
的三个参数的第二个std::type_info const &
无法编译。 clang密码建议我使用两个参数std::common_type
,但这是在模板扩展中,我无法控制输入!
这看起来很奇怪:为什么3 const type_info&
案例失败但其他任何看似等效的类型失败?
答案 0 :(得分:15)
首先,common_type_t<T1, T2>
是(大致)std::decay_t<decltype(true? std::declval<T1>() : std::declval<T2>())>
。它会衰减类型 - 剥离参考,删除顶级cv资格,并执行数组到指针和函数到指针的转换。
所以,common_type<const type_info&, const type_info&>::type
是type_info
。虽然func1
的声明似乎有效,但您在撰写其定义时会遇到严重问题。
common_type_t<T1, T2, T3>
为common_type_t<common_type_t<T1, T2>, T3>
,因此common_type<const type_info&, const type_info&, const type_info&>::type
为common_type<type_info, const type_info&>::type
。
这导致混合值类别三元表达式,[expr.cond]中的规则将尝试从所选操作数中生成临时type_info
- 这不起作用,因为type_info
的复制构造函数已删除。
在SFINAE友好的实施中,导致common_type<const type_info&, const type_info&, const type_info&>
没有成员type
。如果您使用非SFINAE友好的实现,则会收到硬错误。