I'm learning C++ with a small project on SFML, and I wanted to extend the sf::Vector2<T>
class, which represents a 2D math vector. The declaration of this class is available here. In particular, I wanted to add some methods to the class, for norm computation, rotation, etc.
This is what I have so far :
#include <cmath>
#include <SFML/System/Vector2.hpp>
#include <SFML/Graphics/Transform.hpp>
#include <ostream>
namespace dw::math {
template <typename T>
class Vector2 : public sf::Vector2<T> {
public:
// Don't really know what does that exactly means, explainations are welcome !
using sf::Vector2<T>::Vector2;
template <typename U>
explicit Vector2(const U &vector) : sf::Vector2<T>(vector) {}
// This ctor is for implicit conversion from base, don't know if it's really useful ?
Vector2(sf::Vector2<T> &vector) : sf::Vector2<T>(vector) {}
// Some methods here ...
friend std::ostream & operator<<(std::ostream &os, const math::Vector2<T>& right) {
os << '{' << right.x << ", " <<right.y << '}';
return os;
}
};
Later in the code, I have declared such a structure :
struct Derivative {
dw::math::Vector2f dPos;
dw::math::Vector2f dVel;
Derivative() = default;
Derivative(const dw::math::Vector2f &dPos, const dw::math::Vector2f &dVel) : dPos(dPos), dVel(dVel) {}
Derivative operator+(const Derivative &rhs) const {
return Derivative(
dPos + rhs.dPos,
dVel + rhs.dVel
);
}
}
The return part of the operator+
overloading of Derivative
does not compile :
/home/palra/Documents/Projets/dw/src/physics/World.cpp: In member function ‘Derivative Derivative::operator+(const Derivative&) const’:
/home/palra/Documents/Projets/dw/src/physics/World.cpp:24:18: error: invalid user-defined conversion from ‘sf::Vector2<float>’ to ‘const Vector2f& {aka const dw::math::Vector2<float>&}’ [-fpermissive]
dPos + rhs.dPos,
~~~~~^~~~~~~~~~
In file included from /home/palra/Documents/Projets/dw/src/physics/Body.h:8:0,
from /home/palra/Documents/Projets/dw/src/physics/World.h:10,
from /home/palra/Documents/Projets/dw/src/physics/World.cpp:5:
/home/palra/Documents/Projets/dw/src/physics/../math/Vector2.h:30:5: note: candidate is: dw::math::Vector2<T, <template-parameter-1-2> >::Vector2(sf::Vector2<T>&) [with T = float; <template-parameter-1-2> = void] <near match>
Vector2(sf::Vector2<T> &vector) : sf::Vector2<T>(vector) {}
I don't understand why this doesn't work. the expression dPos + rhs.dPos
is compatible with the call of sf::Vector2<float> operator +(const sf::Vector2<float>& left, const sf::Vector2<float>& right)
because a dw::math::Vector2<float>
is a sf::Vector2<float>
by inheritance. This expression is then supposed to yield a sf::Vector2<float>
, which is assignable to the dw::math::Vector2f
thanks to the non explicit constructor I guess. Where I am wrong ? How am I supposed to get it work ?
sf::Vector<T>
wasn't designed to be utilized as derived class, as such a better approach is to write free functions that extend the functionality of sf::Vector<T>
, this works seamless for operators. Unfortunately for normal function calls C++ doesn't support extensions (yet) like C# does.