根据模板参数在编译时安排类结构

发布于 2024-12-15 18:18:09 字数 588 浏览 3 评论 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;
}

所以如果第二个参数为空,则不会有名为 imag 的成员,产生:

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

我尝试了enable_if但无法得到任何结果。

如果这是不可能的,是否有任何技巧可以使其成为可能?

Is is possible in C++ to include/exclude a member variable based on template parameters?

Here is an example:

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

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

As they have many common properties, having only one class to represent a number ( with extra template parameter ) may prevent some code duplications.

What I wanted to do is something like

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

    // If U is not void
    U imag;
}

So if second parameter is void, there would be no member named imag, yielding:

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

I tried enable_if but couldn't get any result.

If this is not possible, are there any hacks that can make this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

剑心龙吟 2024-12-22 18:18:09
typedef NullType struct {} NullType;
template< class T , class U = NullType>
class Number
{
  T real;
  U image;
}
typedef NullType struct {} NullType;
template< class T , class U = NullType>
class Number
{
  T real;
  U image;
}
梦幻的味道 2024-12-22 18:18:09

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

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

template<class T, class U>
class ComplexNumber : public RealNumber<T>
{
  U imag;
};

Check if the inheritance trick is viable for you:

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

template<class T, class U>
class ComplexNumber : public RealNumber<T>
{
  U imag;
};
各自安好 2024-12-22 18:18:09

这个答案不完整,仅显示如何使用 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;
};

详细实施取决于问题的具体性质。
例如,

  • 如果允许实数到复数转换(即 is_a 关系),您可能会考虑从一种实现继承到另一种实现。
  • 要重用大量属性,可以在私有基类中实现公共部分。
  • 根据具体问题,可以检查模板参数 U 是否确实需要。另外,实数 Number 或只是 Number 的首选语法应该是什么。 ETC。

This answer is incomplete and only shows how to use enable_if for specialization of class template.

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

The detail implementation depends on the exact nature of the problem.
Such as,

  • If RealNumber to ComplexNumber conversion is allowed (i.e is_a relationship) , you might consider inheriting from one implementation to another.
  • To reuse large number of properties one can implement the common part in a private base class.
  • Depending on exact problem, one can check if them template parameter U is really needed. Also what should be the preferred syntax for real number Number<int,void> or just Number<int>. etc.
梦过后 2024-12-22 18:18:09

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

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 类型重载,因此你可能需要考虑一个关于您是否真的需要自己写这个。

用法:NumberNumberNumber>

It's very hard to say where you're driving at, but here's a rough skeleton:

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

Note that most standard library numerical functions are already overloaded for the std::complex types, so you may want to think a bit about whether you really need to write this yourself.

Usage: Number<int>, Number<double>, Number<std::pair<double, double>>.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文