使用模板在 class 中设置函数类型会出错
Using Templates to set function types in a class gives error
所以我有这个 class:
template <typename callBackOne,
typename callBackTwo>
class MyClass { // The class
public:
callBackOne cbo;
callBackTwo cbt;
MyClass(callBackOne cbop, callBackTwo cbtp){
cbop();
cbtp();
}
};
它所做的只是调用您在其构造函数参数中提供的函数。
回调函数类型由模板推导出来。我无法以任何其他方式做到这一点。
为什么我尝试时出错:
MyClass<void,void> test(voidFuncOne,voidFuncTwo);
错误:
error: invalid parameter type ‘void’
no matching function for call to ‘MyClass<void, void>::MyClass(int (&)(), void (&)())’
24 | MyClass testy(test,testTwo);
我尝试了很多不同的东西,包括:
MyClass<void(&)(),void(&)()> test(test,testTwo);
MyClass<void,void> test(&test,&testTwo);
MyClass<void (*)(void),void (*)(void)> test(test,testTwo);
我知道可以像这样将函数作为参数传递,但我不知道该怎么做。是语文知识的问题。
Class 成员 cbo
和 cbt
似乎没用:它们没有在 MyClass
的构造函数中分配,根本没有使用。
如果想保存函数指针供以后使用,可以在<functional>
中尝试std::function
。这是一个例子:
#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;
}
模板class的参数类型是void
,但是构造函数的参数类型不是void
类型,这是错误的根本原因。
尝试以下操作:
MyClass<int(), void()> test(voidFuncOne,voidFuncTwo);
或
MyClass<decltype(voidFuncOne),decltype(voidFuncTwo)> test(voidFuncOne,voidFuncTwo);
问题 是您传递的显式模板参数是 void
类型,但函数参数 voidFuncOne
和 voidFuncTwo
将隐式转换为 void (*)()
并传递,但由于没有从 void(*)()
到 void
的转换,您会收到上述错误。
C++17
使用 C++17,您可以使用 class template argument deduction(又名 CTAD),如下所示:
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
//-----^------------------------------->no need to pass arguments explicitly since CTAD will be used
Pre-C++17
在这里您可以显式指定模板参数为 void(*)()
类型,如下所示:
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;
}
//------vvvvvvvvv--vvvvvvvvv--------------------------------->template arguments changed from void to void(*)()
MyClass<void(*)(), void(*)()> test(voidFuncOne,voidFuncTwo);
所以我有这个 class:
template <typename callBackOne,
typename callBackTwo>
class MyClass { // The class
public:
callBackOne cbo;
callBackTwo cbt;
MyClass(callBackOne cbop, callBackTwo cbtp){
cbop();
cbtp();
}
};
它所做的只是调用您在其构造函数参数中提供的函数。 回调函数类型由模板推导出来。我无法以任何其他方式做到这一点。 为什么我尝试时出错:
MyClass<void,void> test(voidFuncOne,voidFuncTwo);
错误:
error: invalid parameter type ‘void’
no matching function for call to ‘MyClass<void, void>::MyClass(int (&)(), void (&)())’
24 | MyClass
我尝试了很多不同的东西,包括:
MyClass<void(&)(),void(&)()> test(test,testTwo);
MyClass<void,void> test(&test,&testTwo);
MyClass<void (*)(void),void (*)(void)> test(test,testTwo);
我知道可以像这样将函数作为参数传递,但我不知道该怎么做。是语文知识的问题。
Class 成员 cbo
和 cbt
似乎没用:它们没有在 MyClass
的构造函数中分配,根本没有使用。
如果想保存函数指针供以后使用,可以在<functional>
中尝试std::function
。这是一个例子:
#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;
}
模板class的参数类型是void
,但是构造函数的参数类型不是void
类型,这是错误的根本原因。
尝试以下操作:
MyClass<int(), void()> test(voidFuncOne,voidFuncTwo);
或
MyClass<decltype(voidFuncOne),decltype(voidFuncTwo)> test(voidFuncOne,voidFuncTwo);
问题 是您传递的显式模板参数是 void
类型,但函数参数 voidFuncOne
和 voidFuncTwo
将隐式转换为 void (*)()
并传递,但由于没有从 void(*)()
到 void
的转换,您会收到上述错误。
C++17
使用 C++17,您可以使用 class template argument deduction(又名 CTAD),如下所示:
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
//-----^------------------------------->no need to pass arguments explicitly since CTAD will be used
Pre-C++17
在这里您可以显式指定模板参数为 void(*)()
类型,如下所示:
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;
}
//------vvvvvvvvv--vvvvvvvvv--------------------------------->template arguments changed from void to void(*)()
MyClass<void(*)(), void(*)()> test(voidFuncOne,voidFuncTwo);