我有下面 3 个类模板。我的问题也在下面的代码中。
#include <array>
template< typename T >
class XY
{
public:
XY() = default;
XY(T x, T y) { vec2 = { x,y }; }
virtual ~XY() = default;
auto X() const -> T { return vec2[0]; }
auto Y() const -> T { return vec2[1]; }
private:
std::array<T, 2> vec2;
};
template< typename T >
class xy
{
public:
xy() = default;
xy(T xx, T yy) : x(xx), y(yy) {}
virtual ~xy() = default;
T x, y;
};
template<typename T>
class coordinates {
public:
T _pp;
void printcoordinates() {
// how can I refer to _pp.x or _pp.X() when it T can be either XY or xy
_pp.x or _pp.X();
_pp.y or _pp.Y();
}
};
}
我有 3 个类模板:
XY
、xy
和 coordinates
。请看上面的代码片段,在coordinates
中,如何引用XY.X()
和xy.x
?
有几个选项。
如果这是您唯一需要的地方,那么
if constexpr
可能是最简单的:
void printcoordinates() {
if constexpr (std::is_same_v<T,XY>)
{
_pp.X();
}
else
{
_pp.x;
}
}
如果您想更频繁地执行此操作,您可能需要使用“特征”模板:
template <typename T>
CoordinatesTraits;
template<>
CoordinatesTraits<XY>
{
int X(XY& p) { return p.X(); }
}
template<>
CoordinatesTraits<xy>
{
int X(xy& p) { return p.x; }
}
void printcoordinates() {
CoordinatesTraits<T>.X(_pp);
}
从技术上来说,你可以这样做:
T _pp;
void printcoordinates() {
if constexpr (requires { _pp.x; }) {
// use _pp.x in here
}
else {
// use _pp.X() in here
}
}
话虽如此,您可能想要做的是使其可配置,无论
_pp
是存储数组还是存储两个成员,并且出于多种原因,您的方法非常疯狂:
virtual
析构函数)。T
,这样您就不需要经历_pp
。
如果你不使用继承,那么虚拟析构函数就完全没有用了。x
和 y
成员,然后重载 operator[]
以便您可以访问其中之一,或者始终直接存储 std::array
。
另请参阅 C++ 通过数组访问多个成员