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
}
A non-template class can have template member functions, if required. Notice the syntax. Unlike a member function for a template class, a template member function is just like a free template function but scoped to its containing class.
Member functions of class templates (C++ only) You may define a template member function outside of its class template definition. The overloaded addition operator has been defined outside of class X . The statement a + 'z' is equivalent to a. operator+('z') .
Member functions can be function templates in several contexts. All functions of class templates are generic but are not referred to as member templates or member function templates. If these member functions take their own template arguments, they are considered to be member function templates.
Member template functions cannot be virtual functions and cannot override virtual functions from a base class when they are declared with the same name as a base class virtual function.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With