-1

I have the following classes and the compiler (Microsoft Visual Studio 2012) gives me strange result since there is no problem compiling a*v but compiling b*v I get the following error:

"error C2678: binary '*': no operator found which takes a right-hand operator of type const double (or there is no acceptable conversion).

The compiler does not use the A::operator*() for a*v, but for b*v the function operator*(U t, Vector<T> v) is used.

So does anyone know what is going on?

template <class T>
class Vector
{
public:
    Vector() { v[0] = 1; v[1] = 2; v[2] = 3; }
    Vector(T a, T b, T c) { v[0] = a; v[1] = b; v[2] = c; }
    T v[3];
};

template <class T, class U>
Vector<U> operator*(const T& t, const Vector<U>& v)
{
    return Vector<U>(t*v.v[0], t* v.v[1], t*v.v[2])
}

class A
{
public:
    Vector<double> operator *(const Vector<double>& v)
    {
        return Vector<double>(99.0,99.0,99.0);
    }
};

class B : public A { };

void MyFct()
{
    Vector<double> v;
    A a;
    B b;
    Vector<double> test1 = a * v;
    Vector<double> test2 = b * v;

    printf("%f %f", test1.v[0], test2.v[0]);
}
Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • I am not quite sure if I got that problem description after the error message right, if not, please [edit] the question to fix it. – Baum mit Augen Mar 07 '16 at 20:45
  • I doubt this would make a difference in terms of creating errors since you didn't #include but Vector is already a class in c++ and I confused your class with the pre-existing Vector class for about a minute. – star2wars3 Mar 07 '16 at 20:45
  • 1
    @star2wars3 The standard class is lowercase, and `#include` is not a thing. But I agree that the name is confusing. – Baum mit Augen Mar 07 '16 at 20:46
  • what about? http://stackoverflow.com/questions/15159020/why-does-an-overloaded-assignment-operator-not-get-inherited – rudolf_franek Mar 07 '16 at 20:49
  • @Baum mit Augen Whoops. This is what happens when I confuse the Java naming convention with that of c++. And your right, it wasn't #include , it was #include (No caps). – star2wars3 Mar 07 '16 at 20:56
  • This code is syntactically incorrect. Can you please make sure you copy and paste the EXACT code you compiled? For a problem like this, small nuances are important. Posting the exact and entire compiler output would be useful too. – M.M Mar 07 '16 at 21:06
  • 1
    @papaDoc `a * v` does use `A::operator*`, not sure why you say in your question that it doesn't – M.M Mar 07 '16 at 21:13
  • @M.M That may actually be my fault, I may have gotten the problem statement wrong while editing. But I'm not sure how to really fix it. – Baum mit Augen Mar 07 '16 at 21:26

2 Answers2

0

This is not a visual studio issue. Clang gives the same error. Which overloaded operator should be used is ambiguous. It appears in the case of the derived class the free operator*() is chosen instead of the member operator*().

The "easy" solution is:

Vector<double> test2 = b.A::operator*(v);

The better solution, IMO, is not to declare operator*() as a member function. Instead overload the the free operator template definition.

Jarra McIntyre
  • 1,265
  • 8
  • 13
0

I'm answering my own question. I was able to make the compilator choose the right function by doing restricting the return value to be created only for arithmetic values

Now with the following free functions, it will exist only for arithmetic value and won't be created for class A and B.

template <class T, class U>
inline Vector<typename std::enable_if<std::is_arithmetic<T>::value, U>::type> operator*(const T& t, const Vector<U>& v)
{
  return Vector<U>(v[0]*t, v[1]*t, v[2]*t);
}