Search code examples
c++templatesconversion-operator

Conversion operator from one templated class to another, related template class


Did search, but couldn't find something that matches my query, it's a bit specific, so here goes.

I have some templated classes (Vector2, Vector3, and Vector4). Trying to define a conversion operator from Vector2 to 3 and 4, and Vector3 to 2 and 4, etc.

template <typename T>
class Vector4 {
    // ...
    operator Vector2<T>() const { return { x, y }; }
    operator Vector3<T>() const { return { x, y, z }; }
    // ...
    T x, y, z, w;
    // ...
}


template <typename T>
class Vector3 {
    // ...
    operator Vector2<T>() const { return { x, y }; }
    operator Vector4<T>() const { return { x, y, z, 0 }; }
    // ...
    T x, y, z;
    // ...
}


template <typename T>
class Vector2 {
    // ...
    operator Vector3<T>() const { return { x, y, 0 }; }
    operator Vector4<T>() const { return { x, y, 0, 0 }; }
    // ...
    T x, y;
    // ...
}

Using Visual Studio 2017 gives me this:

error C2833: 'operator Vector2' is not a recognized operator or type

Any, and all help is appreciated.

Thank you.

Edit: My actual source does have semi-colons after class defs. Forgot to put them in the brief version I posted. Also, yes, there were many errors, but in my experience, it's usually the first one that matters Tried forward declaring:

template <class T> class Vector 3;
template <class T> class Vector 4;

template <typename T> 
class Vector2 {
// ...
}

Edit: Now I get error C2988: unrecognizable template declaration/definition. It's probably worth mentioning that the 3 template classes are in separate files. I originally tried including a header just in one class to get the type conversion operator working, this is what was giving original errors.

Oh, yes. I will definitely be making those explicit. That's always good advice. It was 0430 localtime though... :)

Edit: Nevermind, I'm a spaz. I don't know how I slipped a space in between Vector and the number of dims "Vector 2" != "Vector2". Forward declaration it was. Can't believe I missed something so simple. Kids: Don't code when your so tied, itsa noso good.


Solution

  • When you declare Vector4<T>::operator Vector2<T>() const; you are using the class Vector2<T> before it's been declared. The same thing happens for Vector4<T>::operator Vector3<T>() const;. Forward declare your classes first.

    // Forward declarations
    template<class T> class Vector2;
    template<class T> class Vector3;
    
    template <typename T>
    class Vector4 {
        // ...
        operator Vector2<T>() const { return{ x, y }; }
        operator Vector3<T>() const { return{ x, y, z }; }
        // ...
        T x, y, z, w;
        // ...
    };
    
    
    template <typename T>
    class Vector3 {
        // ...
        operator Vector2<T>() const { return{ x, y }; }
        operator Vector4<T>() const { return{ x, y, z, 0 }; }
        // ...
        T x, y, z;
        // ...
    };
    
    
    template <typename T>
    class Vector2 {
        // ...
        operator Vector3<T>() const { return{ x, y, 0 }; }
        operator Vector4<T>() const { return{ x, y, 0, 0 }; }
        // ...
        T x, y;
        // ...
    };