Pass function as template argument to a class

Related searches

I want to pass functions as template arguments but somehow I can't get it to work. I've written a lot of template classes in the past but only using "normal" types as arguments. I've already searched for that issue but nothing seems to fit here. So I'm stuck.

Here is what I want to achieve: I have a couple of type specific library functions which I want to encapsulate. I know that there are other ways of doing it as well (e.g. inheritance) but since I also want to learn a little bit here, I want to get it done with the template approach.

What I want to achieve:

MyType<int> myIntObject(...);
...
int writeVal = 10;
myIntObject.Write(writeVal);
...
int readVal;
myIntObject.Read(&readVal);

Maybe also using typedefs:

typedef MyType<int> MyIntType;

What I did so far:

template<typename T>
struct SetFunction
{
  inline ret_code operator()(someArgs, T value) const {return E_Fail;}
}

template<typename T>
struct GetFunction
{
  inline ret_code operator()(someArgs, T& value) const {return E_Fail;}
}

//template specialization:
template<>
struct SetFunction<int>
{
  inline ret_code operator()(someArgs, T value) const
  {
    //some other code
    return libraryFunctionWriteInt(someArgs, value);
  }
}

template<>
struct GetFunction<int>
{
  inline ret_code operator()(someArgs, T& value) const
  {
    //some other code
    return libraryFunctionReadInt(someArgs, &value);
  }
}
//do the specialization for all other types as well

template<class T, typename T_get_function = GetFunction<T>(), typename T_set_function = SetFunction<T>()>
MyType
{
public:
  MyType(someArgs)
  {
    if(T_get_function(someArgs, &_value) == E_Fail)
    {
      throw someting;
    }
  }

  bool SetValue(T value)
  {
    _value = value;
    //maybe some other code
    return T_set_function(someArgs, _value) == E_Success;
  }

  bool GetValue(T &value)
  {
    //maybe some other code
    return T_get_function(someArgs, &_value) == E_Success;
  }

private:
  T _value;
}

//and then eventually using it (maybe using some typedefs as well)
MyType<int> myIntObject(someArgs);
...
int writeVal = 10;
myIntObject.SetValue(writeValue);
...
int readVal;
myIntObject.GetValue(&readValue);

Now I get compile errors: expression list treated as compound expression in functional cast on those two lines where I call the T_set_function / T_get_function. I also tried passing the library functions directly as template arguments and don't set any default functions but I couldn't get it to work that way as well.

Almost all of the books, articles and examples I read so far are only dealing with passing "normal" types as template arguments but since stl makes use of passing functions as well I really want to know how to do this.


There is some incomplete code in regard to arguments of operator, but syntax

template<class T, typename T_get_function = GetFunction<T>(), 
                  typename T_set_function = SetFunction<T>()>

is incorrect. typename T_get_function = suggests a type parameter of template, while after = comes an expression GetFunction<T>(), not a declarator.

It should be

template<class T, typename T_get_function = GetFunction<T>, 
              typename T_set_function = SetFunction<T>>

Then it's not clear how you expect T_get_function::operator() to work without instance of class. it's either should be static or you should have an instance.

template<class T, T_get_function getter = GetFunction<T>{}, 
              T_set_function setter = SetFunction<T>>{}

in this particular case typename and class mean same thing and is nt required there. But we don't know what T_get_function is here then? putting it as a class parameter of template and assigning default class is C++20 feature.

Operator & returns a pointer to variable, you can't use it as reference (and you don't need to do that). That metacode contains a several dozen problems ranging from missing ; to incorrect syntax and missing keywords and declarations. If you focus on C++ standard earlier than 2020, you ought to rewrite this from scratch, otherwise use Klaus's answer as guideline.

Passing member functions as template parameters in C++ , Passing member functions as template parameters in C++. Posted: 28th August 2014 by Tim in C++. Tags: class, functions, members, parameter, parameters,� A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function. These function templates can use these parameters as if they were any other regular type.


I don't know if I catch your question, but from the headline I read you want to pass a function as template parameter. That is quite easy, even if you want with function parms or not and with or without return value.

Example:

template < auto func >
struct X
{   
    template < typename ... PARMS >
    static auto call(PARMS&& ... parms)
    {
        return func(parms...);
    }
};  

void func1()           { std::cout << "1" << std::endl; }
void func2(int value ) { std::cout << "2 with " << value << std::endl; }
int  func3()           { std::cout << "With retval" << std::endl; return 987; }

int main()
{   
    X<func1>::call( );
    X<func2>::call( 123 );
    std::cout << "Get retval" << X<func3>::call() << std::endl;
}   

Template parameters and template arguments, Template argument deduction for class templates takes place in declarations and in explicit cast expressions; see� In order for a template to be instantiated, every template parameter (type, non-type, or template) must be replaced by a corresponding template argument. For class templates, the arguments are either explicitly provided, deduced from the initializer, (since C++17) or defaulted.


GetFunction<T> and SetFunction<T> is a functor so you need an instance of it to call its call operator.

Could you replace these parts

  bool SetValue(T value)
  {
    _value = value;
    //maybe some other code
    return T_set_function{ /*Functor constructed*/ }(someArgs, _value) == E_Success;
  }

  bool GetValue(T &value)
  {
    //maybe some other code
    return T_get_function{ /*Functor constructed*/ }(someArgs, &_value) == E_Success;
  }

  if(T_get_function{ /*Functor constructed*/ }(someArgs, &_value) == E_Fail)
  {
    throw someting;
  }

as @Swift-FridayPie said, you also need to re-arrange template parameters part.

Template argument deduction, When instantiating a class template, we have to pass in the types explictly (at least until C++17):. std::vector<int> vec; std� Don’t help the compiler, use template argument deduction. It does the job better than you ever could. In the rare case where template argument deduction does screw up, disable it by putting the argument in a non-deduced context. In cases where template argument deduction isn’t possible, consider using a tag template to enable deduction anyway.


Function templates, Line 1 declares a class template which has two template parameters. at compiletime and std::forward_list does not support the size method. In order to instantiate a function template, every template argument must be known, but not every template argument has to be specified. When possible, the compiler will deduce the missing template arguments from the function arguments. This occurs when a function call is attempted and when an address of a function template is taken.


Types-, Non-Types, and Templates as Template Parameters , The executable for your template version is a whole 25 KB larger than the .exe for your plain old cout version. It probably executes just a little bit slower for the extra function call, but preprocesssing and compiling takes away all the template stuff and just leaves the functions that are the result.


Passing a List as an Argument. You can send any data types of argument to a function (string, number, list, dictionary etc.), and it will be treated as the same data type inside the function. E.g. if you send a List as an argument, it will still be a List when it reaches the function: