如何实现在实例(前置)之前可用的操作符

How to implement an operator usable before an instance (pre position)

本文关键字:操作符 实例 何实现 实现 前置      更新时间:2023-10-16

我有一个类,其中operator*以标量作为参数,这允许我用标量执行类的实例的乘法。我希望能够将一个标量乘以我的类的一个实例(反序与相同的结果)。我该怎么做呢?

下面是一个例子:

class Vector3d
{
public:
    Vector3d(double x, double y, double z) {
        v[0] = x; v[1] = y; v[2] = z;
    }
    template<typename T>
    Vector3d operator*(const T s) const {
        return( Vector3d( v[0] * s, v[1] * s, v[2] * s)); 
    }
//protected: example purpose
    double v[3];
};
main()
{
    double scalar = 2.0;
    Vector3d vector(1.0,2.0,3.0);
    Vector3d v2 = vector*scalar;
    //This is the operation I want to be able to perform !
    //Vector3d v3 = scalar*vector; 
    return 0;
}

我试图实现它,就像我们做ostream<<操作符没有成功…

template<typename T>
Vector3d operator*(T& s, const Vector3d &v)
{
    return( Vector3d( v[0] * s, v[1] * s, v[2] * s));
} 

必须将操作符*声明为参数顺序相反的非成员函数(类外),并从中调用另一个

template<typename T>
Vector3d<T> operator*(T& s, const Vector3d<T> &v)
{
    return Vector3d(v.v[0] * s, v.v[1] * s, v.v[2] * s);
} 
template<typename T>
Vector3d<T> operator*(const Vector3d<T> &v, T& s)
{
    return s * v; //call the other overload
} 

不要忘记指定模板参数:

Vector3d<T>
        ^^^

还有一个问题…为什么用T&代替const T&T ?在当前形式中,您阻止传递右值。例如,这不会编译:

Vector3d<int> v;
v*3; //3 isn't an lvalue, cannot bind to a nonconst reference

最好在类之外重载操作符,这样可以提供最大的灵活性。

//编译得很好

class Vector3d
{
public:
    Vector3d(double x, double y, double z) {
        v[0] = x; v[1] = y; v[2] = z;
    }
    double v[3];
};
template<typename T>
Vector3d operator*(const T& s, const Vector3d &v) 
{
    return( Vector3d( v.v[0] * s, v.v[1] * s, v.v[2] * s)); 
}
int main(int argc, char **argv)
{
    double scalar = 2.0;
    Vector3d vector(1.0,2.0,3.0);
    Vector3d v3 = scalar * vector; 
    return 0;
}