Home > Software design >  Using Templates to set function types in a class gives error
Using Templates to set function types in a class gives error

Time:05-11

So I have this class:

 template <typename callBackOne,
           typename callBackTwo>
class MyClass {       // The class
  public: 
    callBackOne cbo;
    callBackTwo cbt;           
    MyClass(callBackOne cbop, callBackTwo cbtp){
      cbop();
      cbtp();
    }
};

All it does is call the functions you give in the parameter for its constructor. The callback function types are deduced by a template. I cannot do this any other way. Why does it error when I try:

MyClass<void,void> test(voidFuncOne,voidFuncTwo);

The error:

error: invalid parameter type ‘void’
no matching function for call to ‘MyClass<void, void>::MyClass(int (&)(), void (&)())’

24 | MyClass<void,void> testy(test,testTwo);

Ive tried lots of different things including:

MyClass<void(&)(),void(&)()> test(test,testTwo);
MyClass<void,void> test(&test,&testTwo);
MyClass<void (*)(void),void (*)(void)> test(test,testTwo);

I know its possible to pass in functions as parameters like this but i just cant figure out how. Its a problem of knowledge of the language.

CodePudding user response:

Class member cbo and cbt seems useless: they are not assigned in MyClass's constructor and are not used at all.

If you want to save function pointers for later use, you can try std::function in <functional>. Here is an example:

#include <iostream>
#include <functional>

template <typename callBackOne,  typename callBackTwo>
class MyClass {       // The class
public:
    std::function<callBackOne> cbo;
    std::function<callBackTwo> cbt;

    MyClass(callBackOne cbop, callBackTwo cbtp) : cbo(cbop), cbt(cbtp) {
    }
};

void voidFuncOne() { std::cout << "One\n"; }
void voidFuncTwo() { std::cout << "Two\n"; }

int main()
{
    MyClass<void(), void()> test(voidFuncOne, voidFuncTwo);
    test.cbo();
    test.cbt();
    return 0;
}

CodePudding user response:

The parameter type of the template class is void, but the parameter type of the constructor is not the void type, which is the root cause of the error.

try the following:

MyClass<int(), void()> test(voidFuncOne,voidFuncTwo);

or

MyClass<decltype(voidFuncOne),decltype(voidFuncTwo)> test(voidFuncOne,voidFuncTwo);

CodePudding user response:

The problem is that the explicit template arguments that you're passing are of type void but the function arguments voidFuncOne and voidFuncTwo will be implicitly converted to void (*)() and passed but since there is no conversion from a void(*)() to void you get the mentioned error.

With C 17, you can make use of class template argument deduction(aka CTAD) as shown below:

template <typename callBackOne,
           typename callBackTwo>
class MyClass {       // The class
  public: 
    callBackOne cbo;
    callBackTwo cbt;           
    MyClass(callBackOne cbop, callBackTwo cbtp){
      cbop();
      cbtp();
    }
};
void voidFuncOne()
{
    std::cout<<"funcone called"<<std::endl;
}
void voidFuncTwo()
{
    std::cout<<"functow called"<<std::endl;
}
MyClass test(voidFuncOne,voidFuncTwo); //CTAD used automatically here
  • Related