std::is_same 类型相等性检查的荒谬行为
std::is_same absurd behaviour on type equality check
考虑以下代码:
struct A
{
using type = int;
using reference = int&;
};
static_assert(std::is_same_v<A::type&, A::reference>); // <-- Success, as it would be
static_assert(std::is_same_v<const A::type&, const A::reference>); // <-- Fail!!
这是怎么回事??为什么他们不再是同一种类型了?我花了很多时间找到这个,它看起来确实是一个编译器错误
首先,const int&
可以说是对常量int的引用,而不是对int的常量引用。因此,将 const
关键字添加到 A::reference
会产生拼写为 int& const
而不是 const int&
的野兽(或同样好 int const &
)。
所以是的,因为不能将引用重新绑定到不同的对象,所以它实际上是常量,没有任何关键字。因此 const
在一个符号之后是多余的。看起来它已被默默删除,我无法引用所需编译器行为的标准,请参阅@Quentin 的评论。
其次,答案可能取决于您真正想要实现的目标。如果 A
是一个容器,它应该有一个 A::const_reference
成员类型,您应该使用它。如果它是一个更通用的范围而不是容器,它的 reference
和 const_reference
成员类型可能是两个完全不相关的代理对象 类。如果您控制 A
,请添加 const_reference
成员类型。否则,@Evg 提供了一个可行的解决方案。也许更简单的解决方案就是 const std::decay_t<A::reference>&
。
考虑以下代码:
struct A
{
using type = int;
using reference = int&;
};
static_assert(std::is_same_v<A::type&, A::reference>); // <-- Success, as it would be
static_assert(std::is_same_v<const A::type&, const A::reference>); // <-- Fail!!
这是怎么回事??为什么他们不再是同一种类型了?我花了很多时间找到这个,它看起来确实是一个编译器错误
首先,const int&
可以说是对常量int的引用,而不是对int的常量引用。因此,将 const
关键字添加到 A::reference
会产生拼写为 int& const
而不是 const int&
的野兽(或同样好 int const &
)。
所以是的,因为不能将引用重新绑定到不同的对象,所以它实际上是常量,没有任何关键字。因此 const
在一个符号之后是多余的。看起来它已被默默删除,我无法引用所需编译器行为的标准,请参阅@Quentin 的评论。
其次,答案可能取决于您真正想要实现的目标。如果 A
是一个容器,它应该有一个 A::const_reference
成员类型,您应该使用它。如果它是一个更通用的范围而不是容器,它的 reference
和 const_reference
成员类型可能是两个完全不相关的代理对象 类。如果您控制 A
,请添加 const_reference
成员类型。否则,@Evg 提供了一个可行的解决方案。也许更简单的解决方案就是 const std::decay_t<A::reference>&
。