有没有办法在非模板类中定义模板成员?

时间:2019-03-26 12:49:52

标签: c++ class templates

假设我有一个名为Compute的类模板,以及另一个具有成员函数模板的名为Function_A的类:

template <typename T> void Evaluate(T parameter)

我必须按原样使用类Function_A。我已经知道T只能是type_1type_2两种类型之一。

是否有一种方法可以将Compute<T> C作为Function_A的成员变量,而不是在Compute<T>内定义局部Evaluate(...)对象?我知道这与使用模板的原则背道而驰,因此这不可能实现,但是理想情况下可以这样做吗?

我尝试在Compute<type_1> C1中有两个成员Compute<type_2> C2Function_A,然后在if (typeid(T) == typeid(type_1))下使用它们,但这很丑陋,并且违反了使用哲学模板。

只是为了说明我的意思:

template <class T>
class Compute
{
public:
  T Function_B(T parameter)
    {
      return f.eval(parameter);
    }

private:
  SomeClass<T> f;
}

还有一个班级

class Function_A
{
  public:
    template <typename T> T Evaluate(T parameter)
    {
      Compute<T> C; //this is very expensive!
      T value = C.Function_B(parameter);
      return value;
    }

  private:
    double SomeParameter;
    //Compute<T> C; //conceptually what I want
}

2 个答案:

答案 0 :(得分:10)

(未试用)如何:

class Function_A
{
  public:
    template <typename T> void Evaluate(T parameter)
    {
      T value = std::get<Compute<T>>(computers).Function_B(parameter);
      return T(SomeParameter) * value;
    }

  private:
    double SomeParameter;
    std::tuple<Compute<type_1>, Compute<type_2>> computers;
};

注意:如果您喜欢std::pair所添加的第一个/第二个语义,则其工作原理与std::tuple完全相同。

另外,请注意T(SomeParameter)是C样式的强制转换,如果T不是类类型,则可能会出现问题。考虑使用T{}static_cast<T>()

答案 1 :(得分:3)

您可以做的一件事就是制作C static。如果有

template <typename T> void Evaluate(T parameter)
{
  static Compute<T> C; // only do this once per T now
  T value = C.Function_B(parameter);
  return T(SomeParameter)*value;
}

然后,当您使用Evaluate调用type_1时,将具有其中包含C<type_1>的函数的一个版本,该版本仅在第一次调用该函数时构造,并且type_2也会发生同样的事情。