简体   繁体   中英

Is there a way to define a template member in a non-template class?

Say I have a class template named Compute , and another class named Function_A with a member function template:

template <typename T> void Evaluate(T parameter)

I am constrained to use the class Function_A as it is. I already know that T can only be one of two types type_1 and type_2 .

Is there a way to have something similar to Compute<T> C as a member variable of Function_A instead of defining a local Compute<T> object inside Evaluate(...) ? I know that this is against the philosophy of using templates, hence it is likely not possible, but can ideally be done in that case instead?

I tried to have two members Compute<type_1> C1 and Compute<type_2> C2 in Function_A , and then use them under an if (typeid(T) == typeid(type_1)) but it's a pretty hideous, and against the philosophy of using templates as well.

Just to illustrate what I mean:

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

private:
  SomeClass<T> f;
}

And a class:

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
}

How about (untested):

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

Note: std::pair would work exactly the same as std::tuple here, if you fancy the first/second semantics it adds.

Additionally, note that T(SomeParameter) is a C-style cast, which could be problematic if T is not a class type. Consider T{} or static_cast<T>() .

One thing you can do is make C static . If you have

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

then when you call Evaluate with type_1 you'll have one version of the function that has C<type_1> in it that will only be constructed the first time the function is called and the same thing happens for type_2 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM