【问题标题】:Why is the const qualifier in this type alias dropped? [duplicate]为什么此类型别名中的 const 限定符被删除? [复制]
【发布时间】:2018-11-01 09:13:46
【问题描述】:

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 上不应编译的示例。

详情

我有一个模板类,它接受一堆迭代器(-types)作为模板参数。从这些迭代器中,我需要推断出引用和 const 引用类型,因为我有一些成员函数,例如:

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 成员函数,因此编译器会抛出异常。

【问题讨论】:

  • referencestring&amp;const reference其实就是string&amp; const
  • 编译器实际上给了你一个非常明确的警告:"'const' 对引用类型 'A::reference' (aka ...) 的限定符没有效果 [-Wignored-qualifiers] "
  • @Peter 但是iterator_traits 没有const_reference 类型。
  • @Holt 是的,我看到了那个警告,但我不知道为什么它会弹出。

标签: c++ c++17 qualifiers


【解决方案1】:

丢弃了。我们所说的“const 引用”实际上是对 const 的引用 - const int&amp;

拥有int&amp; 并添加const 将使int&amp; const。但是这样的 const 被删除了。

您的问题类似于const int*int* const 之间的区别。除了引用之外,int&amp;int&amp; const 是同一类型 - const 被忽略。

【讨论】:

  • 我很难相信某处没有骗子。
  • 可能有。我开始是作为评论,就像你一样,但它变得太大而无法容纳。 :-)
  • 如果你正确地表达了这个问题,可能会有重复。但是,如果您不知道问题的根源,就很难正确表述它。
  • @Timo - 这可能行得通。我会使用std::vector&lt;std::string&gt;::const_reference 并避免玩杂耍链锯。
  • 所以我可以把它想象成,OP 正在做的是const (T&amp;),但他们真正想要的是(const T)&amp;remove_reference 技巧会起作用,因为您可以从 (T&amp;) 中提取 T,添加 const,然后放回引用。
【解决方案2】:

你的问题是west const。 West const is bad const 东 const 是最好的 const。

West const 将 const 放在要成为 const 的标记的左侧。 East const 将其放在右侧。

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

using const_reference = reference const;

您可能会弄清楚为什么const 不起作用。天真地扩展参考后,您会得到string&amp;const——在这里,您尝试将const 应用于&amp; 而不是string,并且foo &amp;constfoo const&amp; 不同——foo&amp;const 只是foo&amp; as const 不能应用于引用本身,而只能应用于所引用的类型。

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

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

要理解 const,请将您的 const 转换为east const。 West const 只是标准 east const 规则的一个例外,如果左侧的类型中没有标记,则它适用于右侧的标记。这里右边的标记是整个类型string&amp; 捆绑到一个类型别名中(类型别名不是宏)。相反,如果您键入 const string&amp;,则右侧的标记将是 string,您将得到 string const&amp; 理智的东部常量风格。

East const 是最好的 const。

【讨论】:

  • 我不知道为什么我觉得这很搞笑
  • 我喜欢西方和东方 const 的术语 :)
猜你喜欢
  • 2016-02-14
  • 2017-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-20
  • 2019-01-16
  • 2016-04-06
相关资源
最近更新 更多