如何在类模板中引用类成员

问题描述 投票:0回答:2

我有下面 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

c++ templates
2个回答
1
投票

有几个选项。

如果这是您唯一需要的地方,那么

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);
}

0
投票

从技术上来说,你可以这样做:

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++ 通过数组访问多个成员
© www.soinside.com 2019 - 2024. All rights reserved.