首页 > 解决方案 > std::is_same 类型相等检查的荒谬行为

问题描述

考虑以下代码:

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!!

到底是怎么回事??为什么它们不再是同一类型了?我花了很多时间找到这个,它看起来确实是一个编译器错误

标签: c++is-same

解决方案


首先,const int&可以说是对常量 int 的引用,而不是对 int 的常量引用。因此,添加const关键字 toA::reference会产生一个拼写为 asint& const而不是const int&(或同样好int const &)的野兽。

所以是的,因为一个引用不能被反弹到不同的对象,它实际上是没有任何关键字的常量。因此,const在&符号之后是多余的。看起来它被默默地丢弃了,我无法引用所需编译器行为的标准,请参阅@Quentin 的评论。

其次,答案可能取决于您真正想要实现的目标。如果A是一个容器,它应该有一个A::const_reference成员类型,你应该使用它。如果它是一个更通用的范围而不是容器,它referenceconst_reference成员类型可能是两个完全不相关的代理对象类。如果您控制A,请添加const_reference成员类型。否则,@Evg 提供了一个可行的解决方案。也许更简单的解决方案就是const std::decay_t<A::reference>&.


推荐阅读