c++ 2 overloads have similar conversions depending on whether the operator is a member function or a global one

  ambiguous, c++, operator-overloading

Consider a simple vector class realization:

#include <algorithm>

class Vector {
public:
    Vector(int _elementsCount)
        : elementsCount(_elementsCount)
        , elements(new float[_elementsCount])
    {}
    ~Vector() {
        delete[] elements;
    }
    Vector(const Vector& rhs) {
        elementsCount = rhs.size();
        elements = new float[elementsCount];
        for (int i = 0; i < elementsCount; ++i)
            (*this)[i] = rhs[i];
    }

    float& operator [](int i) {
        return elements[i];
    }
    float operator [](int i) const {
        return const_cast<Vector&>(*this)[i];
    }
    int size() const {
        return elementsCount;
    }
    /*// Dot product
    float operator *(const Vector& v) {
        float res = 0;
        for (int i = 0; i < size(); ++i)
            res += (*this)[i] * v[i];
        return res;
    }*/
private:
    int elementsCount;
    float* elements;
};

// Multiplication by a scalar
Vector operator *(const Vector& v, float k) {
    Vector res(v.size());
    for (int i = 0; i < v.size(); ++i)
        res[i] = v[i] * k;
    return res;
}

// Dot product
float operator *(const Vector& v1, const Vector& v2) {
    float res = 0;
    for (int i = 0; i < std::min(v1.size(), v2.size()); ++i)
        res += v1[i] * v2[i];
    return res;
}

void main()
{
    Vector v(2);
    v * 3; // ambiguous
}

This code compiles. But if we uncomment * operator realization in the class and comment its global realization (dot product function), then there will be an error "’Vector::operator *’: 2 overloads have similar conversions", because there is an ambiguity: whether to call the multiplication by a scalar or to interpret 3 as an argument to a parametrized constructor and to call the dot product. This makes sense. But I don’t get what’s the difference of declaring the * operator as a member function or as a global function. I thought they should be the same in the example like above, but it’s not the case.

Source: Windows Questions C++

LEAVE A COMMENT