0

I have a template vector class, and I am trying to overload the arithmetic operators such that adding/subtracting vectors of different primitive types will yield a vector of the primitive type returned by the arithmetic operation (i.e., adding a vector of int and a vector of double will yield a vector of double). The relevant code follows:

template<typename T> class Vector { private: T x, y, z; public: // constructors, destructors, etc. T X() const { return ( this->x ); } T Y() const { return ( this->y ); } T Z() const { return ( this->z ); } template<typename U> auto operator+(const Vector<U> &v) const -> Vector<decltype(this->x + v.X())> { return ( Vector<decltype(this->x + v.X())>( this->x + v.X(), this->y + v.Y(), this->z + v.Z() ) ); } }; 

Then, in main.cpp:

Vector<double> d1(1,2,3), d2(4,5,6); std::cout << d1 + d2; 

I get the following error from Visual Studio 2012:

error C2893: Failed to specialize function template 'Vector<T> Vector<double>::operator +(const Vector<U> &) const' with [ T=unknown ] With the following template arguments: 'double' error C2676: binary '+' : 'Vector<T>' does not define this operator or a conversion to a type acceptable to the predefined operator with [ T=double ] 

Please advise.

1
  • Try to upgrade to visual-studio-2013. works with gcc (ideone.com/GlJOcE) Commented Jan 27, 2015 at 16:58

1 Answer 1

1

Visual C++ fails to determine the correct type of your decltype expression. By replacing your expression with decltype(*((T*)0) + *((U*)0)) you remove the dependency on this and the argument v, which leads to the intended result on VS as well.

Note: Bug was reproducable on VS2013.4 on which the fix was tested as well.

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you! That works. I am confused by the expression you have here; can you explain its meaning?
@LRC It dereferences a (null) pointer of appropriate type to create an lvalue of T and U respectively. This way, they need not be constructible in any specific way.
Thank you for the explanation! That makes perfect sense!
decltype(std::declval<T>() + std::declval<U>()) seems more readable.
@Jarod42 I agree, I was just too lazy to figure out if declval was supported on VS2012 already.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.