0

在 C++ 中是否可以根据模板参数包含/排除成员变量?

这是一个例子:

template< class T >
class RealNumber
{
    T real;
};

template< class T >
class ComplexNumber
{
    T real;
    T imag;
};

由于它们有许多共同的属性,只有一个类来表示一个数字(带有额外的模板参数)可以防止一些代码重复。

我想做的是

template< class T , class U >
Number
{
    T real;

    // If U is not void
    U imag;
}

因此,如果第二个参数为 void,则不会有名为 imag 的成员,产生:

sizeof( Number< T , void > ) == sizeof( T )

我尝试了 enable_if 但没有得到任何结果。

如果这是不可能的,是否有任何黑客可以使这成为可能?

4

4 回答 4

1
typedef NullType struct {} NullType;
template< class T , class U = NullType>
class Number
{
  T real;
  U image;
}
于 2011-11-14T04:12:45.713 回答
1

该答案不完整,仅显示如何enable_if用于类模板的专业化。

template<class T,class U,class Enable = void>
class Number
{
  T real;
  T imag;
};
template<class T,class U>
class Number<T,U,typename std::enable_if<std::is_void<U>::value>::type>
{
  T real;
};

详细的实现取决于问题的确切性质。如,

  • 如果允许 RealNumber 到 ComplexNumber 的转换(即is_a关系),您可以考虑从一个实现继承到另一个实现。
  • 要重用大量属性,可以在私有基类中实现公共部分。
  • 根据具体问题,可以检查它们U是否真的需要模板参数。还有什么应该是实数的首选语法Number<int,void>或只是Number<int>. 等等
于 2011-11-14T07:14:02.610 回答
1

检查继承技巧是否适合您:

template<class T, class = void >
class RealNumber
{
  protected: T real;
};

template<class T, class U>
class ComplexNumber : public RealNumber<T>
{
  U imag;
};
于 2011-11-14T04:30:55.063 回答
0

很难说你在哪里开车,但这里有一个粗略的骨架:

template <typename T> class Number
{
  template <typename S> class Adder
  {
    typedef S type;
    static type add(type a, type b) { return a + b; }
  };
  template <typename U, typename W> class Adder<std::pair<U,W>>
  {
    typedef typename std::pair<U,W> type;
    static type add(type a, type b) { return type(a.first + b.first, a.second + b.second); }
  };

  T val;

public:
  T operator+(const T rhs) { return Adder<T>::add(val, rhs); }
};

请注意,大多数标准库数值函数已经为这些std::complex类型重载,因此您可能需要考虑一下是否真的需要自己编写。

用法:Number<int>, Number<double>, Number<std::pair<double, double>>.

于 2011-11-14T04:20:28.780 回答