根据模板参数更改member-typedef?

时间:2014-06-05 06:56:54

标签: c++ templates c-preprocessor

我这里有这个问题,我无法弄清楚如何解决。我想要一个模板类,它接受一个整数作为模板参数,并相应地设置另一个类的模板参数:

template <int T>
class Solver
{

  public:

    #if T <= 24
      typedef MyMatrix<float> Matrix;
    #else if T <= 53
      typedef MyMatrix<double> Matrix;
    #else
      typedef MyMatrix<mpreal> Matrix;
    #endif

    Matrix create();

};

然后这样称呼它:

Solver<53>::Matrix m = Solver<53>::create();

我该怎么办?目前使用上面的代码,编译器抱怨它不知道&#34; Matrix&#34;,所以我不确定你是否可以在模板参数上使用预处理器。

3 个答案:

答案 0 :(得分:10)

引言

由于您希望S<N>::Matrix根据传递的 N 产生不同的类型,因此您需要使用某种元模板编程。该问题目前使用预处理程序标记,并且代码段明确尝试使用它;但在这种情况下,这几乎没有用。

当代码被预处理时N只不过是一个名字,它没有一个值;爱好。


解决方案

说明中提到 if if ...... else else ;我们正在处理类型..通过<type_traits>查看std::conditional似乎是一个完美的匹配!

std::conditional<condition, type-if-true, type-if-false>::type;

注意:根据condition中的表达式是否产生 true false ,{{1对于 type-if-true type-if-false ,将是 typedef 。功能


让我们编写一个示例实现:

::type

#include <type_traits>

template <int N>
class Solver
{
  public:
    typedef typename std::conditional<
      /*    */ (N <= 24),
      /* y? */ MyMatrix<float>,
      /* n? */ typename std::conditional<(N <= 53), MyMatrix<double>, MyMatrix<mpreal>>::type
    >::type matrix_type;

  ...
};

答案 1 :(得分:4)

你可以使用std::conditional来做这件事,不过你是否应该首先这样做是另一条鱼:

template<int T>
class Solver
{
  std::conditional_t<
    T <= 24,
    MyMatrix<float>,
    std::conditional_t<
      T <= 53,
      MyMatrix<double>,
      MyMatrix<mpreal>
    >
  > Matrix;
};

如果您的编译器不支持,则需要使用std::conditional::type代替conditional_t

答案 2 :(得分:1)

不,您无法在模板参数上使用预处理器。

预处理器只是对输入源进行非常简单的字符串处理。它没有关于类型的粘合剂,我认为它是在第一次处理文件和收集所有包含时的第一步。模板是编译器自己处理的东西。此时预处理器已经完成。

这里有一个类似的问题: Use a template parameter in a preprocessor directive?