为什么删除此类型别名中的 const 限定符?

Why is the const qualifier in this type alias dropped?

TL;DR

给定以下类型:

struct A
{
    std::vector<std::string> vec;

    using reference = std::iterator_traits<decltype(vec)::iterator>::reference;
    using const_reference = const reference;
};

为什么是reference == const_reference?为什么 const 限定符在第二个类型别名中被删除?

请参阅 godbold 上的示例,该示例不应编译。

详情

我有一个模板化的 class,它将一堆迭代器(-types)作为模板参数。我需要从这些迭代器中推导出引用和常量引用类型,因为我有一些成员函数,例如:

struct A
{
    std::vector<std::string> vec;

    using reference = std::iterator_traits<decltype(vec)::iterator>::reference;
    using const_reference = const reference;

    const_reference foo() const
    {
        return vec[0];
    }
};

通过删除 const 限定符,我实际上在 foo 中返回了一个引用,这是非法的,因为它是一个 const 成员函数,因此编译器会抛出异常。

掉线了。我们所说的 "const reference" 实际上是对 const 的引用 - const int&.

有一个 int& 并添加 const 将得到 int& const。但是这样一个const被丢弃了。

你的问题类似于const int*int* const的区别。除了引用,int&int& const 是同一类型 - const 被忽略。

你的问题是west const。西方 const 是不好的 const 东方 const 是最好的 const。

West const 是把const 放在你想成为const 的标记的左边。 East const 放在右边。

如果我告诉你永远不要把 const 放在类型的左边,并且 const 总是应用于 左边的东西,看看这个:

using const_reference = reference const;

您大概可以弄清楚为什么 const 不起作用。天真地扩展引用后,您会得到 string&const——这里您尝试将 const 应用于 & 而不是 string,并且 foo &constfoo const& -- foo&const 只是一个 foo&,因为 const 不能应用于引用本身,而只能应用于引用的类型。

当然,你说,但这就是我想要 west const 的原因!

West const 在这里做同样的事情。它适用于 & 而不是 string 然后被丢弃。它只是以一种更令人困惑且更难直观理解的方式来实现。

要理解 const,请将您的 const 转换为 east const。 West const 只是标准 east const 规则的一个例外,如果左侧的类型中没有标记,则它适用于右侧的标记。此处右侧的标记是捆绑到类型别名中的整个类型 string&(类型别名不是宏)。相反,如果您键入 const string&,则右侧的标记将是 string,并且您会得到 string const& 以正常的东方常量样式。

East const 是最好的const.