【问题标题】:C++ specialized template class for a given type list给定类型列表的 C++ 专用模板类
【发布时间】:2015-03-19 03:24:18
【问题描述】:

我正在编写一种稀疏矩阵实现,实际上有两种不同的实现:一种用于轻类型(即sizeof(T) <= sizeof(int64),另一种用于重类型。

根据sizeof(T),我想实例化对应的类。我首先使用实例化 HeavyTypeLightType 实现的超类进行了测试,但这需要从通用虚拟 BaseClass继承轻型和重型>,而通用调用类以这种方式使用一种或另一种(不是很干净):

template <class T> class Generic{
public:
 Generic(){
   if (sizeof(T) > TRESHOLDVALUE)
    matrix_ = new HeavyType<T>();
   else
    matrix_ = new LightType<T>();
  }
private:
 matrix_ * BaseClass<T>;
};

这可行,但不干净,BaseClass 中的虚拟化会减慢执行速度...

我想只写一个模板类,并将它专门用于几种类型,但我想知道:是否可以专门针对sizeof(T) 的特定值(即相当于@987654325 @)?或可能的类型数组 (template &lt;&gt; class Matrix&lt;arrayOfPossibleTypes&gt; )?

我想避免为intbooluint_32int32etc 类型重写类。

有人有想法吗?

PS: 或者,我想用一个预编译器宏来选择 LightTypeHeavyType 类,但我认为在 #if 预编译器语句中使用 sizeof() 是不可能的.

【问题讨论】:

  • std::conditional 可能会有所帮助。

标签: c++ templates c-preprocessor


【解决方案1】:

此问题的一个解决方案是std::enable_if(如果您使用的是 C++11)或boost::enable_if(如果您使用的是旧标准)。您可以在模板中添加一个额外的虚拟模板参数:

template <class T, typename Enable = void> class Generic;

template <class T>
class Generic<T, typename boost::enable_if_c<sizeof(T) > TRESHOLDVALUE>::type>
{
    // implementation for "heavy" class
    HeavyType<T> matrix_;
};

template <class T>
class Generic<T, typename boost::disable_if_c<sizeof(T) > TRESHOLDVALUE>::type>
{
    // implementation for "light" class
    LightType<T> matrix_;
};

如果您确实需要对“轻量级”和“重度”进行不同的实现,这将是最好的。如果您要做的只是更改matrix_ 成员的类型,而您的所有其余实现保持不变,那么您可以使用std::conditional(或其等效的Boost,boost::mpl::if_c)。

【讨论】:

  • 我会说enable_if 对于一个简单的bool 会做的事情来说太过分了。
  • 确实,在这种情况下,专门研究 bool 的值也足够了。
  • 在这种情况下我不喜欢使用外部依赖。 Boost 是一个非常强大但很重的外部依赖。 ;)
【解决方案2】:

使用std::conditional,您可以执行以下操作:

template <class T> class Generic{
public:
    using MatrixType = typename std::conditional<(sizeof(T) > TRESHOLDVALUE), HeavyType<T>, LightType<T>>::type;
 Generic() {}
private:
 MatrixType  matrix_;
};

【讨论】:

    【解决方案3】:

    你说得对,在预处理器指令中不能使用sizeof。而且这不是必需的,您可以专注于sizeof(T) 就好了。事实上,你可以专攻sizeof(T) &lt;= sizeof(int64)

    template <class T>
    class Generic{
    private:
     MatrixType<T> matrix_;
    };
    
    template <class T, bool Light = sizeof(T) <= sizeof(int64)>
    struct MatrixType;
    
    template <class T>
    struct MatrixType<T, true>
    {
      //light matrix
    };
    
    template <class T>
    struct MatrixType<T, false>
    {
      //heavy matrix
    };
    

    【讨论】:

    • 感谢您的提示。不知道您可以在模板类型定义中放置条件语句。这非常有效。
    • @Danduk82 需要明确的是,该条件语句是默认模板参数。它仍然可以被例如覆盖。正在做MatrixType&lt;int, false&gt;,但您可以将其隐藏在实现细节中。
    猜你喜欢
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多