【问题标题】:C++ candidate function not viable?C++ 候选函数不可行?
【发布时间】:2020-06-12 23:01:58
【问题描述】:

为什么下面的代码不能编译:

B b1(1), b2(2), b3(3);
const B b4 = b1 + (b2 + b3);

直到我替换这个:

B operator+(B& b) {
    return B(n + b.n);
}

有了这个:(不知道编译器提示为什么要写const)

B operator+(const B& b) {
    return B(n + b.n);
}

我得到的错误:

二进制表达式的无效操作数('B' 和 'B')

注意:候选函数不可行:期望第一个 l 值 论据

注意:候选模板被忽略:无法匹配 'reverse_iterator' 针对 'B' 运算符+(类型名 reverse_iterator<_iter>::difference_type __n, const reverse_iterator<_iter>& __x)

另外,为什么这样有效? (和上一个案例类似)

bool Test(int x)
{
    return x==0;
}
Test(0);

【问题讨论】:

  • 临时对象不能绑定到非常量左值引用。
  • 顺便说一句,你还是错过了const:B operator+(const B&amp; b) const。
  • b1 和其余的不是临时的@Jarod42
  • 它可以在没有其他 const 的情况下工作
  • 加上为什么更改参数(而不是返回值)作为 const 解决了这个问题?可能有人发布完整的答案,这没有意义

标签: c++ class


【解决方案1】:
const B b4 = b1 + (b2 + b3);

根据运算顺序,第一个求值的子表达式是b2 + b3。这会调用B::operator+,它返回一个B 对象。更准确地说,一个 temporary B 对象被返回,该对象将用于帮助评估这个完整的表达式,然后被丢弃。这很像在草稿纸上做笔记,同时手动进行长时间的计算。

下一个要计算的子表达式是b1 加上临时对象。这将使用临时 B 对象作为参数调用 b1.operator+。当操作员的签名是

B operator+(B& b)

有一个问题,因为 C++ 语言声明 a non-const reference cannot bind to a temporary object。即引用参数(B&amp; b)与临时对象不匹配。您可以通过将引用从不符合 const-qualified 的引用更改为符合的引用来解决此问题。

B operator+(const B& b)

此版本的运算符采用const 引用,可以绑定到临时对象。 (同样,这只是语言的规则。你可以争论它的原因,但规则仍然有效。)

请注意,这不是一个完整的解决方案,因为加法往往是对称的。为了适应括号左侧为const-qualified 的情况,*this 也需要为const-qualified。

B operator+(const B& b) const

有关更多提示,请参阅the basic rules and idioms for operator overloading。您可能会发现您不一定希望 operator+ 成为成员函数。

【讨论】:

  • 谢谢,但是 (b2 + b3) + b1 没有为此添加 const 就可以工作
  • (b2+b3)+b1 有效(临时为*this)。失败的是 b4+b1(b4 是 const)。
  • @Jarod42 这是临时工的怪事之一吗?呸。如果您编写可靠的代码,您就会忘记代码在触发实际错误之前必须变得多糟糕的复杂性......
  • @zoorish 抱歉,我在发布之前没有测试代码。我经常这样做,但在这种情况下,模拟 B 似乎工作量太大。 (这意味着如果您在问题中提供了B 的最小定义——我可以复制——我会通过编译器传递代码来仔细检查。)
猜你喜欢
  • 2021-12-31
  • 2016-01-12
  • 1970-01-01
  • 2010-10-31
  • 2019-08-19
  • 1970-01-01
  • 2014-01-22
  • 2020-07-30
  • 1970-01-01
相关资源
最近更新 更多