基于L值与R值的重载

时间:2014-05-05 16:40:55

标签: c++ overloading

我在C ++书中发现了以下内容:

  

虽然我们不会在本书中这样做,但你可以重载一个   函数名称(或运算符),以便在使用时表现不同   作为l值并且当它用作r值时。 (回想一下   l值意味着它可以在赋值的左侧使用   声明。)例如,如果你想要一个函数f来表现   取决于它是用作l值还是用作l值   r值,你可以这样做:

class SomeClass { 
public:
  int& f(); // will be used in any l-value invocation const 
  const int& f( ) const; // used in any r-value invocation ... 
};

我尝试过这个并没有用:

class Foo {
        public:
        int& id(int& a);
        const int& id(int& a) const;
};

int main() {
        int a;
        Foo f;
        f.id(a) = 2;
        a = f.id(a);
        cout << f.id(a) << endl;
}

int& Foo :: id(int& a) {
        cout << "Bar\n";
        return a;
}

const int& Foo :: id(int& a) const {
        cout << "No bar !\n";
        return a;
}

我是否错误地理解了它?

3 个答案:

答案 0 :(得分:3)

这本书的例子都是错误的,或者你从书中复制了错误的例子。

class SomeClass { 
public:
  int& f(); // will be used in any l-value invocation const 
  const int& f( ) const; // used in any r-value invocation ... 
};

使用此代码,当您致电s.f(),其中sSomeClass类型的对象时,s为非{{1}时将调用第一个版本当consts时,将调用第二个版本。价值类别与它无关。

参考资格如下:

const

答案 1 :(得分:1)

当然这本书是correct。让我解释作者的意思的一个例子的工作原理:

#include <iostream>
using namespace std;

class CO
{
    int _m;
public:
    CO(int m) : _m(m) {}
    int& m()             { return _m; } // used as an l-value
    int const& m() const { return _m; } // used as an r-value
};

int main() 
{
    CO a(1);

    cout << a.m() << endl;

    a.m() = 2; // here used as an l-value / overload resolution selects the correct one

    cout << a.m() << endl;

    return 0;
}

输出

  

1

     

2

你误解的是功能签名。你看到你有一个参数&arg(如在id(&arg)中)你几乎预定了它的l-valuness,所以通过const或非const成员函数返回它不会改变一个东西。 / p>

作者提到了一种通用的写作风格,允许“吸气者”。和&#39;塞特斯&#39;使用仅在const限定符中签名的签名进行声明,但编译和行为正确。

修改

更迂腐,以下短语

  

回想一下l值意味着它可以在赋值语句的左侧使用。

不再有效。 lr 评价适用于表达式,最简单的解释方法是,我们可以采用的表达式是一个l值;如果它不可获得它是一个r值。

因此作者引用的语法强制在赋值运算符的两侧正确使用成员函数(正确的编译/重载解析)。现在这与 lr 价值不再相关。

答案 2 :(得分:0)

只能在const对象上调用const成员函数。您对返回值的处理方式没有区别。在您的示例中,f是非const,因此它始终调用f()的非const版本。请注意,您还可以在C ++ 11中重载r值引用(&&)。