3

我有一个类,我重载了 [ 运算符以在 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 '[' : no operator found 之类的错误,它采用'const ArithmeticVector' 类型的左操作数

问题在于这条线。

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

重载运算符不喜欢它:/

4

2 回答 2

3

我不明白,你的意思是什么,但你也应该为 const 版本I want to use [] operator like the old style重载:operator[]

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

v1并且v2在这里不可修改,它们不能调用非常量方法。

于 2013-05-19T18:38:24.190 回答
2

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

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

并且 v1 和 v2 都是类型const ArithmeticVector<T>&,这意味着编译器将尝试为它们找到operator[](int) const它们(它们是常量对象)。当您按照上述答案中的建议重载 const 运算符时,您可以重用 const 运算符中的代码,只需通过丢弃对象的 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上有一个答案,它谈到了这一点。

您还需要注意避免浮点异常(除以零)或 SIGFPE,这将在 时发生v3[i] == 0,您可以通过稳定结果来做到这一点(您会失去准确性):

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

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

于 2013-05-19T19:00:19.603 回答