【问题标题】:C++: const reference, before vs after type-specifierC++:常量引用,在类型说明符之前 vs 之后
【发布时间】:2022-01-08 09:29:02
【问题描述】:

中的参数有什么区别:

int foo1(const Fred &arg) {
...
}

int foo2(Fred const &arg) {
...
}

? 我在 parashift 常见问题解答中没有看到这种情况。

【问题讨论】:

  • 这是关于风格的问题吗? “const Fred”在英语中听起来不错,但“Fred const”在我看来更好。
  • 在相关说明中,有什么理由应该更喜欢Fred const &arg 而不是Fred const& arg?我更喜欢后者,因为const& 是一个单位,意思是“constref”,名称arg 与所有类型说明符用空格隔开。
  • @dehmann:但int const& ref 并不是指“const ref”而是“ref to const”。

标签: c++ reference constants


【解决方案1】:

行为

const T&T const&之间没有语义上的区别;语言将它们视为同一类型。 (同样的事情适用于const T*T const*。)

风格问题

然而,关于你应该在风格上更喜欢哪个,我会反对很多其他答案,更喜欢const T&(和const T*):

  • const T& 是 Stroustrup 的C++ 编程语言一书中使用的风格。
  • const T& 是 C++ 标准本身使用的样式。
  • const T* 是 K&R 的 The C Programming Language 一书中使用的风格。
  • const T* 是 C 标准中使用的样式。
  • 由于以上因素,我认为const T&/const T*T const&/T const*有更大的惯性。在我见过的所有 C++ 和 C 代码中,const T&/const T* 在经验上对我来说似乎比 T const&/T const* 更常见。我认为遵循常规做法比教条地坚持从右到左的解析规则更具可读性。
  • 使用T const*,似乎更容易将* 误认为T* const(尤其是如果人们不习惯它)。相反,const* T 是不合法的语法。

从右到左的解析规则呢?

关于人们似乎喜欢使用的整个从右到左的解析参数:正如我在对另一个答案的评论中提到的那样,const T& 从右到左读起来也很好。它是对 T 常数的引用。 “T”和“常数”都可以用作形容词或名词。 (此外,从右到左读取 T const* 可能会产生歧义,因为它可能被错误地解释为“指针常量 to T”而不是“指针 to 常量 T "。)

【讨论】:

  • +1,同意。阅读代码时,如果行以 const 开头,则更容易发现 const。仅在手动解析特别多毛的类型声明时才真正需要左右规则。为什么不针对最常见的情况进行优化?此外,恕我直言,如果您编写类型声明,那么您需要在头脑中手动运行 FSM,那么您做错了。
  • -1。无论您的结论有多么合理,以及我个人多么同意这些结论,他们都没有直接回答所提出的问题。这使得对一个简单问题的第二多答案看起来像是关于一些混乱的水下机械的题外话,没有结论,没有直接的答案——什么都没有。当您添加一个简单清晰的摘要说明“不,两种语法之间没有语义差异,但有一些风格上的考虑如下......”时,您会得到我的支持。只有这样所有的子弹。
  • IMO const T& 读起来更好的原因是: 1- 我们从左到右阅读代码。 2-在描述一个新概念时,我们从更一般的概念开始到更具体的概念。在这里,const 关键字更通用,因为它将变量空间划分为两个类别,而类型说明符将其划分为多个类别。
  • “指针”应该保持在一起。所以T const*没有歧义
  • @Dexter 虽然“指向”的指针应该保持一致,但要记住并可能出错是另一回事。
【解决方案2】:

No difference 因为 const 相对于 & 是从右到左读取的,因此两者都表示对不可变 Fred 实例的引用。

Fred& const 表示引用本身是不可变的,即redundant;在处理 const pointers 时,Fred const*Fred* const 都有效但不同。

这是风格问题,但我更喜欢使用 const 作为后缀,因为它可以一致地应用,包括 const member functions

【讨论】:

  • 那么让std::is_const<const T&>::value 成为false 有什么意义呢?
  • @abyss.7 这是对const T的引用;引用是可变的。
  • 如果根据定义,引用不能重新绑定,引用如何可变,而这正是这个问题及其答案所讨论的内容 - T& const 的概念是多余的?这是一个关于is_const 的非常有效的问题,我也想知道答案。
  • @VioletGiraffe 确实引用不能被重新绑定,所以在这个意义上引用是不可变的。最好简单地说引用忽略引用本身上的 const 限定符:“引用类型不能在顶层进行 cv 限定;声明中没有语法,并且如果将限定添加到 typedef -name 或 decltype 说明符,或类型模板参数,它被忽略。" (见cppreference.com
【解决方案3】:

虽然它们是一回事,但为了与 RIGHT-LEFT 关于解析 C 和 C++ 声明的规则保持一致,最好写成 Fred const &arg

另请参阅this 以进一步了解声明、限定符和声明符。

【讨论】:

  • 我更喜欢这个后缀,因为它更适合typedef 扩展。示例:typedef int* pointer;const pointer 不是 const int*,是int* const。后缀形式不尴尬。
  • IMO const T& 从右到左读取也很好;它是对 T 常数的引用。 Tconstant 都可以用作形容词或名词。
【解决方案4】:

两者都有效,here 是写它的人的解释。
引用他的话:

为什么?当我发明“const”时 (最初命名为“只读”并有一个 对应的“只写”),我允许 它在类型之前或之后 因为我可以这样做 模棱两可。

【讨论】:

    【解决方案5】:

    【讨论】:

      【解决方案6】:

      【讨论】:

        【解决方案7】:

        引用与指针的工作方式不同:对于指针,您可以使用“const 指针”(type * const p)和“指向 const 的指针”(const type * ptype const * p)。

        但是你没有这个作为引用:一个引用总是指向同一个对象;从这个意义上说,您可以认为“引用”是“常量引用”(与拥有“常量指针”的方式相同)。

        因此,像 'type & const ref' 这样的东西是不合法的。您只能拥有“对类型的引用”(type &ref)和“对常量类型的引用”(const type &reftype const &ref;两者完全相同)。

        最后一件事:即使const type 在英语中听起来更正确,写作type const 可以更系统地理解“从右到左”的声明:int const & ref can be read has 'ref is a reference to an constant诠释'。或者更复杂的例子:int const * const & ref, ref 是一个指向常量 int 的常量指针的引用。

        结论:在你的问题中,两者是完全等价的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-01-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多