【问题标题】:Wording of GCC's error message when calling lvalue-ref qualified member function on temporary object在临时对象上调用 lvalue-ref 限定成员函数时 GCC 错误消息的措辞
【发布时间】:2020-11-05 21:59:51
【问题描述】:

预计以下代码无法编译:

struct A {
    void doWork() & {}
};
int main() {
    A{}.doWork();
}

我的理解是临时的A{} 不能绑定到& 限定的成员函数doWork,这似乎与cppreference 的摘录一致(我的斜体) :

[...] 类 X 的成员函数处理如下:

  • 没有引用限定符:隐式对象参数具有对 cv 限定 X 的左值引用类型,并且还允许绑定右值隐含对象参数
  • 左值引用限定符:隐式对象参数具有对 cv 限定 X 的左值引用类型并且不允许绑定右值隐含对象参数
  • rvalue ref-qualifier:隐式对象参数的类型为 cv-qualified X 的右值引用

我在 Vim 中使用的 clangd 也告诉我

'this' 成员函数 'doWork' 的参数是一个右值,但函数有非const lvalue ref-qualifier deleteme.cpp:2:10: 注意:'doWork' 在这里声明[member_function_call_bad_ref]

但是,当我使用 GCC 编译时,我得到了这个错误:

$ g++ -std=c++17 deleteme.cpp && ./a.out
deleteme.cpp: In function ‘int main()’:
deleteme.cpp:16:16: error: passing ‘A’ as ‘this’ argument discards qualifiers [-fpermissive]
   16 |     A{}.doWork();
      |                ^
deleteme.cpp:5:10: note:   in call to ‘void A::doWork() &’
    5 |     void doWork() & {
      |          ^~~~~~

这似乎不像来自clangd的错误那样与错误相关。

另一方面,当我错误地调用 non-const member function on const object 时,我读过这两个词,discards qualifiers;在这种情况下,我理解“丢弃”的使用,因为该对象有一个函数无法兑现的const,因此应该丢弃它以使事情正常工作。

但是,上面的代码似乎并非如此,据我了解,问题在于A{} 的右值性与doWork() & 所期望的左值性相比。

来自 GCC 的错误措辞是错误的还是我误读了?

【问题讨论】:

  • 为什么-1???请解释原因,所以我编辑问题以改进它。
  • @TonyK,已删除,但这怎么会刺痛我?这不是无害的吗?
  • 是的,我想这里是无害的。但是多余的分号肯定会在函数体内引起问题。 (此外,它会让你看起来好像不知道自己在做什么。)
  • 该标准没有规定错误信息的措辞,因此在法律上没有对错之分。
  • @cigien “丢弃限定符”诊断是正确的:引用限定符也是限定符 除了A{} 和应用于它的临时实现转换都没有限定符。并且表达式没有可以丢弃的引用限定符。

标签: c++ gcc ref-qualifier


【解决方案1】:

这只是 GCC 中措辞欠佳的错误消息。

我的猜测是,在 GCC 的实现中,诊断不同 ref-qualifiers 之间的不匹配与诊断 const 和 non-const 之间的不匹配共享一些代码,并且它们重用了相同的错误消息。

我鼓励您file a GCC bug 建议改进错误消息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-04
    • 2015-02-13
    • 1970-01-01
    • 2015-11-14
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多