同时使用普通和重载运算符

时间:2013-05-19 18:33:44

标签: c++ operator-overloading friend

我有一个类,我重载[运算符在main中使用。但这里的问题是;在另一个函数的类中的某个地方。我想使用[老式的操作员。我如何使用它们或如何修改我的重载[参数?

这是重载部分。

T &operator[](int i)
{
if (i < 0 || i >= ArithmeticVector<T>::size())
   throw std::string("Out of bounds!"); //throw std::out_of_range;
else
   return data[i];
};

这是我想要使用的另一个功能;

friend ArithmeticVector<T> operator /(const ArithmeticVector<T>& v1, const ArithmeticVector<T>& v2 )
{  
/*Do quick size check on vectors before proceeding*/
ArithmeticVector<T> result(v1.size());
   for (unsigned int i = 0; i < result.size(); ++i)
{
   result[i]=v1[i]/v2[i];
}
   return result;
};

我得到错误,如错误C2678:binary'[':找不到运算符,它接受类型为'const ArithmeticVector'的左手操作数

问题出在这条线上。

result[i]=v1[i]/v2[i];

重载运算符不喜欢它:/

2 个答案:

答案 0 :(得分:3)

我无法理解,I want to use [] operator like the old style是什么意思,但你也应该为const版本重载operator[]

const T& operator[](int i) const
{
    // ...
}

v1v2在这里不可修改,它们不能调用非const方法。

答案 1 :(得分:2)

您还需要重载const对象的访问运算符,因为表达式result[i] = v1[1] / v2 [i]的r.h.s将计算为:

v1.operator[](i) / v2.operator[](i)

并且v1和v2都是const ArithmeticVector<T>&类型,这意味着编译器将尝试为它们找到operator[](int) const(它们是常量对象)。当您按照上面的答案中的建议重载const的运算符时,可以重新使用const运算符中的代码,只需通过抛弃对象的constness来调用非const运算符中的运算符。这样,您就不必考虑在一个操作符中实现的内容并将其移植到另一个操作符,并且您不必在两个位置调试代码。这是你的问题的模型(我没有你的ArithmeticVector的实现,所以你必须使用它的部分为你的东西):

template<typename T>
class ArithmeticVector;

template<typename T>
ArithmeticVector<T> operator / (
    const ArithmeticVector<T>& v1, 
    const ArithmeticVector<T>& v2
);

template<typename T>
class ArithmeticVector 
{
    public:

        // Your declaration
        T& operator[](int i)
        {
            // Casting away constness allows code re-use. 
            return const_cast<ArithmeticVector&>(*this).operator[](i);
        }

        // Const declaration:
        T& operator[](int i) const
        {
            // Put your operator code here. 
        }

        friend ArithmeticVector<T> operator / <> (
            const ArithmeticVector<T>& v1, 
            const ArithmeticVector<T>& v2
        );
};

template<typename T>
ArithmeticVector<T> operator / (
    const ArithmeticVector<T>& v1, 
    const ArithmeticVector<T>& v2
)
{
    //ArithmeticVector<T> result(v1.size());
    ArithmeticVector<T> result;

    result[0]=v1[0]/v2[0];

    return result;
};


int main(int argc, const char *argv[])
{

    ArithmeticVector<int> v1, v2, v3; 

    v1 = v2 / v3;

    return 0;
}

Scott Meyers有一本很棒的书“Effective C ++”,你可以在那里阅读关于对象和访问操作符的常量的精彩描述。 SO上有一个answer,可以讨论这个问题。

您还需要注意避免浮点异常(除以零)或SIGFPE,这将在v3[i] == 0时发生,您可以通过稳定结果(松散准确度)来执行:< / p>

result[i] = v1[i] / (v2[I] + 1e-15)

或者你引入了一个显着减慢divison的测试(如if if v2[i] == 0)。