Reputation: 322
I am trying to represent points in two "types of space": Window space and world space. I have a 2d vector class which is the raw data.
What is the best way to "strongly type" these two without re-writing my 2d vector class? Ie i would have to re-write all the operator+= operator-, operator+ and so forth.
My current code for the two points is below. I'm looking for a "better solution". I define better as strong typing, and able to write code like this:
pos += {0, -1};
Without having to write a full suite of operators for WindowPosition and WorldPosition.
My current solution:
struct WindowPosition
{
template<typename... Args>
WindowPosition(Args&&... args)
: m_coords(std::forward<Args>(args)...)
{}
operator math::v2&() { return m_coords; }
operator const math::v2&() const { return m_coords; };
math::v2 m_coords;
};
struct WorldPosition
{
template<typename... Args>
WorldPosition(Args&&... args)
: m_coords(std::forward<Args>(args)...)
{}
operator math::v2&() { return m_coords; }
operator const math::v2&() const { return m_coords; };
WindowPosition ToWindowPosition()
{
return globals::CAMERA->ToWindowRelative(m_coords);
}
math::v2 m_coords;
};
But this means I have to do this instead: pos.m_coords += {0, -1};
Is there a better way to achieve what I've described above? Or is there a more idiomatic solution?
****EDIT: here is what I ended up going with. Thanks @jzwinck:
struct Window {};
struct World {};
template <typename Tag>
struct Position : math::v2
{
template<typename... Args>
Position(Args&&... args)
: math::v2(std::forward<Args>(args)...)
{}
};
typedef Position<Window> WindowPosition;
typedef Position<World> WorldPosition;
WindowPosition ToWindowPosition(const WorldPosition& pos)
{
return globals::CAMERA->ToWindowRelative(pos);
}
Upvotes: 1
Views: 66
Reputation: 249394
Templates!
struct Window {};
struct World {};
template <typename Tag>
struct Position
{
template<typename... Args>
Position(Args&&... args)
: m_coords(std::forward<Args>(args)...)
{}
operator math::v2&() { return m_coords; }
operator const math::v2&() const { return m_coords; };
math::v2 m_coords;
};
typedef Position<Window> WindowPosition;
typedef Position<World> WorldPosition;
WindowPosition ToWindowPosition(const WorldPosition& pos)
{
return globals::CAMERA->ToWindowRelative(pos);
}
Upvotes: 4