Как реализовать оператор, используемый перед экземпляром (предварительная позиция) - PullRequest
3 голосов
/ 07 июля 2011

У меня есть класс с 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));
} 

Ответы [ 2 ]

4 голосов
/ 07 июля 2011

Вы должны объявить свой оператор * как функцию, не являющуюся членом (вне класса) с обратным порядком аргументов, и вызвать другой из нее

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
1 голос
/ 07 июля 2011

Лучше всего выполнять перегрузку операторов вне класса, что обеспечивает максимальную гибкость.

// Это прекрасно компилируется.

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;
}
...