【问题标题】:Reference to double and double returned by operator[] methods with the same argument signature对具有相同参数签名的 operator[] 方法返回的 double 和 double 的引用
【发布时间】:2016-11-01 18:36:11
【问题描述】:

我正在阅读 Wikipedia 上有关表达式模板的文章。

https://en.wikipedia.org/wiki/Expression_templates#Motivation_and_example

本节有两个公共方法:

double &operator[](size_t i)      { return elems[i]; }
double operator[](size_t i) const { return elems[i]; }

第一个似乎返回一个对 double 的非常量引用,而第二个返回一个 const double。这两种方法怎么可能存在于同一个类中?

【问题讨论】:

    标签: c++ templates operator-overloading


    【解决方案1】:

    你不能仅仅通过返回类型来区分,但是你可以有不同的成员函数来区分它们是否对对象的const实例进行操作。

    使用链接中代码的示例:

    #include <vector>
    #include <assert.h>
    
    class Vec {
        std::vector<double> elems;
    
    public:
        Vec(size_t n) : elems(n) {}
    
        double &operator[](size_t i) { return elems[i]; }
        double operator[](size_t i) const { return elems[i]; }
        size_t size()               const { return elems.size(); }
    };
    
    Vec operator+(Vec const &u, Vec const &v) {
        assert(u.size() == v.size());
        Vec sum(u.size());
        for(size_t i = 0; i < u.size(); i++) {
            sum[i] = u[i] + v[i];
        }
        return sum;
    }
    
    int main()
    {
        Vec vec1{5};
        auto val1 = vec1[2]; // calls the first
        const Vec vec1r{5};
        auto val1c = vec1r[2]; // calls the second
        return 0;
    }
    

    为什么 elems[i] 可以将 reference 返回到 double 的一个方法, 而elems[i] 可以为另一个返回double

    这些是不同的功能:

    double &operator[](size_t i);
    double operator[](size_t i) const;
    

    因此可能会返回不同的类型。

    Elems 是std::vector&lt;double&gt;elems[i] 有时怎么会返回一个 引用double,有时返回double

    在第一种情况下不复制值,只返回引用。返回值在第二种情况下被复制。

    std::vector&lt;double&gt;::operator[] 在第一种情况下返回一个引用,在第二种情况下返回一个const 引用。但如前所述,在第二种情况下,从std::vector 收到的const 引用被Vec 的函数复制作为返回值。

    【讨论】:

    • 我不知道。那么,为什么第一种方法前面要加一个 & 号呢?
    • @AaronF 因为语法允许使用混淆符号。返回类型为double&amp;
    • 第一个确实返回了 double &amp; 非常量引用。可能值得查找如何阅读函数声明。
    • Elems 是一个 std::vector。 elems[i] 如何有时返回对双精度的引用,有时返回双精度?
    【解决方案2】:

    第一个似乎返回对双精度的非常量引用,

    是的,double &amp; 是对 double 的非常量引用。

    而第二个返回一个 const double。

    不,它只是按值返回 double

    这两种方法如何存在于同一个类中?

    const 限定了方法,而不是返回类型。您可以重载 const-qualification。

    this 指针视为隐式参数 - 您可以根据它是否指向 const 对象来重载该方法,就像任何其他参数一样。


    例如,这些重载是合法的,但因为它们是在参数类型上重载的,而不是在返回类型上。 (一旦你有一个允许的重载,你当然可以有不同的返回类型,这还不够)。

    int  deref(const int *p) { return *p; }
    int& deref(int *p)       { return *p; }
    
    const int i = 42;
    int j = deref(&i); // ok, returns by value
    // deref(&i) = 24; // not ok, assigns to temporary
    deref(&j) = 24;    // ok again, this uses the second overload
    assert(i == 42);
    assert(j == 24);
    

    同样适用于方法,但使用不同的语法(this 指针是隐式的,因此您不能直接将其写为带/不带const 的参数)

    【讨论】:

      【解决方案3】:

      成员函数声明末尾的const 表示当类的对象为const 时,它是可调用的。 (它不适用于返回类型。)

      因此,如果v 不是const-qualified,则表达式v[i] 调用第一个,如果vconst-qualified,则调用第二个。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-28
        • 2012-12-02
        • 1970-01-01
        • 1970-01-01
        • 2013-07-27
        • 1970-01-01
        相关资源
        最近更新 更多