std::common_type with references to type_info

std::common_type with references to type_info

本文关键字:type to info references with std common      更新时间:2023-10-16

我很困惑:在升级到GCC 6(RC1)时,一些使用std::common_type的模板代码失败了。我试过叮当,但也失败了。。。所以我一定做错了什么!

代码总计为:

#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();

具有三个类型为std::type_info const &的参数的第二个common_type编译失败。clang隐晦地建议我使用双参数std::common_type,但这是在模板扩展中,我无法控制输入!

这似乎很奇怪:为什么3的const type_info&案例会失败,而其他看似等效的类型却没有失败?

请参见此处:https://godbolt.org/g/Ob4y0x

首先,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&>::typecommon_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友好的实现,您将得到一个硬错误。

相关文章: