Home > Software design >  C Template class member function that returns the same template class data type
C Template class member function that returns the same template class data type

Time:08-15

I'm trying to make a proof-of-concept class template that makes a 2D vector. I'm trying to make a member function that returns a "flipped" version of the vector were x becomes y and vice versa. I want the function to return the Vector2 template class data type. This is my syntax:

Class:

template<class T>
class Vector2
{
private:
    T m_x;
    T m_y;
public:
    Vector2();
    Vector2(const T& x, const T& y);
    T getX();
    T getY();
    void setX(const T& x);
    void setY(const T& y);
    template <class U> friend Vector2<U> getFlippedCopy();
};

The syntax for the flip function:

template <class T>
Vector2<T> Vector2<T>::getFlippedCopy()
{
    Vector2<T> vectorCopy;
    vectorCopy.setX(m_y);
    vectorCopy.setY(m_x);
    return vectorCopy;
}

However, I get an error:

classes.hpp:51:12: error: no declaration matches ‘Vector2<T> Vector2<T>::getFlippedCopy()’
   51 | Vector2<T> Vector2<T>::getFlippedCopy()
      |            ^~~~~~~~~~
classes.hpp:51:12: note: no functions named ‘Vector2<T> Vector2<T>::getFlippedCopy()’
classes.hpp:4:7: note: ‘class Vector2<T>’ defined here
    4 | class Vector2
      |       ^~~~~~~

Also, where is a good resource to properly learn templates and all their complexities? I find lots of YouTube videos don't go beyond the basics or skim over complicated stuff...

CodePudding user response:

You are trying to define a member function named getFlippedCopy but you haven't declared such a function.

I suspect that you've made a mistake by instead declaring a free friend function with the same name. I suggest making it a member function instead, which should then be const qualified:

template<class T>
class Vector2 {
    //...
    // note: not a function template:
    Vector2 getFlippedCopy() const;
};

template <class T>
Vector2<T> Vector2<T>::getFlippedCopy() const {
    Vector2<T> vectorCopy;
    vectorCopy.setX(m_y);
    vectorCopy.setY(m_x);
    return vectorCopy;
}

CodePudding user response:

Your function, getFlippedCopy(), does 2 things:

  • creates a copy
  • flips x and y

If you decouple the two steps, it'll be easier.

You can simply add a copy ctor and a flip() method:

Vector2(const Vector2& other)
: m_x(other.m_x), m_y(other.m_y) {}

void flip() { std::swap(x, y); }

Then, if you want a helper that does copy-and-flip:

// inside Vector's definition
Vector2 getFlippedCopy() const
{
    Vector2 ret(*this);
    ret.flip();
}

Also, don't do getX() and setX(): if you have both, that means the member should be public.

  • Related