为什么我的类使用了错误的operator()?

问题描述 投票:0回答:1

考虑下面的类

Foo
,它提供了 2 个运算符
()
,一个用于读取,另一个用于写入。

#include <iostream>
    #include <vector>

    template <typename T>
    class Foo {
     public:
      Foo(const std::vector<T> &values) { vals = values; }
      const T &operator()(const int i, const int j) const {
        std::cout << "Read" << std::endl;
        return vals[i];
      }
      T &operator()(const int i, const int j) {
        std::cout << "Write" << std::endl;
        return vals[i];
      } 

     private:
      std::vector<T> vals;
    };

    int main() {
      std::vector<int> values(100, 1);

      Foo<int> f{values};
      f(1,1) = 42; //here it writes:OK
      std::cout << f(1,1) << std::endl; //why is again the "read" version called?
      return 0;
    }

我无法理解为什么在我的代码中只调用“write”版本。

c++ templates generics operator-overloading
1个回答
0
投票

问题是

f
非const,这意味着非常量成员函数版本比const成员函数版本更好匹配,因为非常量版本的
this
的类型是
Foo<int>*
,而对于 const 版本,它是
const Foo<int>*
,因此后者需要 资格转换,而前者则不需要,因此更好的匹配

要解决这个问题,您可以将

f
设置为常量(但随后您将无法在其上写入)或在非常量
const_cast
上使用
f
,如下所示:

int main() 
{
      std::vector<int> values(100, 1);

      Foo<int> f{values};  //non-const f
      f(1,1) = 42; //uses write version
      std::cout << const_cast<const Foo<int>&>(f)(1, 1) << '\n'; //use const_cast 
      return 0;
}

工作演示

© www.soinside.com 2019 - 2024. All rights reserved.