重载订阅运算符()或[],不重复代码

时间:2013-09-09 15:14:00

标签: c++ optimization operators operator-overloading

我有两个版本的operator():

const A& operator(int x ,int y) const;
A& operator(int x ,int y);

但我不知道避免代码重复的最佳方法是什么(因为它们基本上具有相同的逻辑)。

我确实阅读了关于运算符重载的常见问题解答(以及其他一些问题),但未找到答案。

EDIT_1:我已经尝试过Skizz提出的建议,但这样的事情对我来说并不适用,但也许我错过了一些东西:

因为this有效而this无法编译而导致以下错误:

错误:从'const value_type {aka const int}'类型的表达式初始化'int&'类型的引用无效

3 个答案:

答案 0 :(得分:2)

如果两种方法“基本上具有相同的逻辑”,那么它们肯定都应该标记为const。如果他们的行为有所不同,他们应该被称为同一件事吗?

你需要的是第三个隐藏的方法,它可以做到这一点: -

const A& operator(int x ,int y) const
{
  return Common (x,y);
}
A& operator(int x ,int y)
{
  return Common (x,y);
}
A& Common (int x, int y) const
{
   // common code
}

这利用了隐式的非const到const转换。在第一种方法中,此对象在对Common的调用中保持const,但非const返回值将转换为const。在第二个中,非const此对象被转换为const此对象,并且返回对象不变。

答案 1 :(得分:1)

如果您将相关数据视为共享/唯一指针,则可以将其转发到常用功能:

class X {
    public: 
    const A& operator () (int x ,int y) const { 
        common(data, x, y);
        return *data;
    }

    A& operator () (int x ,int y) { 
        common(data, x, y);
        return *data;
    }

    private:
    void common(std::shared_ptr<T>, int x ,int y) const;
    std::shared_ptr<A> data;
};

现在您可以通过data.get()访问T *,它是'T * get()const'。 (注意:我认为常用功能设计不好)

您可能也会这样做:

class X {
    public:
    const A& operator () (int x ,int y) const { 
        common(x, y); 
        return data;
    }

    A& operator () (int x ,int y) { 
       // ... make mutations
       common(x, y); 
       // ... make mutations
       return data;
    }

    void common(std::shared_ptr<T>, int x ,int y) const;
    T data;
};

或者实际上,如果数据没有破坏逻辑const,那么使数据可变:

class X {     
    const A& operator () (int x ,int y) const { 
        // ... make mutations on the mutable data, only
        return *lazy_evaluated_data;
    }

    A& operator () (int x ,int y) { 
        const X& self = *this;
        self(x, y);
        return *lazy_evaluated_data;;
    }

    private:
    mutable T lazy_evaluated_data; // or a cache
};

答案 2 :(得分:0)

编写一个辅助函数并从两个运算符中调用它。你需要做一些可能很难看的const_cast<...>(this),但这是一种常见的模式。