可变参数模板,std::function 和 lambda 作为 class 成员
Variadic Templates, std::function and lambdas as class members
我这里有几个 classes,第一个是存储 std::function
类型的 class。
template<typename RES_TYPE, typename... ARG_TYPES>
struct Functor {
std::function<RES_TYPE( ARG_TYPES... )> call_back;
};
我有另一个 class,它将从函数对象、函数指针或 lambda 中注册一个传入函数,并存储上述 class 的实例,并具有另一个将调用的成员函数它。
template<typename RES_TYPE, typename... ARG_TYPES>
class Driver {
private:
Functor<RES_TYPE, ARG_TYPES...> callback_;
public:
Driver() = default;
~Driver() = default;
void register_callback( const Functor<RES_TYPE, ARG_TYPES...> &func ) {
callback_ = func;
}
RES_TYPE call_back( ARG_TYPES... args ) {
return callback_( args... );
}
};
我正在努力使语法正确到我试图在尝试调用它时传递函数值的位置。我的主要看起来像这样:
int main() {
Functor<int, int, int> func;
auto lambda = []( int a, int b ) { return a + b; };
func.call_back = lambda;
Driver<int, int, int> driver;
driver.register_callback( func );
std::cout << driver.call_back( 3, 5 ) << '\n';
return 0;
}
我似乎无法理解语法中缺少的内容。我已经尝试了其他各种方法,但是使用当前设置,我从 Visual Studio 2017 CE:
得到了这个编译器错误
1>------ Build started: Project: Temp, Configuration: Debug Win32 ------
1>main.cpp
1>c:\...\main.cpp(62): error C2064: term does not evaluate to a function taking 2 arguments
1>c:\...\main.cpp(62): note: while compiling class template member function 'RES_TYPE Driver<RES_TYPE,int,int>::call_back(int,int)'
1> with
1> [
1> RES_TYPE=int
1> ]
1>c:\...\main.cpp(77): note: see reference to function template instantiation 'RES_TYPE Driver<RES_TYPE,int,int>::call_back(int,int)' being compiled
1> with
1> [
1> RES_TYPE=int
1> ]
1>c:\...\main.cpp(75): note: see reference to class template instantiation 'Driver<int,int,int>' being compiled
1>Done building project "Temp.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
我知道编译器在告诉我什么,但我似乎无法获得正确的语法来存储此 lambda,然后再调用它。我试图让这些 classes 尽可能通用,以便它可以接受 lambda、函数对象或函数指针。
解决方案
我的代码现在看起来像这样并且工作正常!
template<typename RES_TYPE, typename... ARG_TYPES>
struct Functor {
std::function<RES_TYPE( ARG_TYPES... )> func_;
};
template<typename RES_TYPE, typename... ARG_TYPES>
class Driver {
private:
Functor<RES_TYPE, ARG_TYPES...> functor;
public:
Driver() = default;
~Driver() = default;
void register_callback( const Functor<RES_TYPE, ARG_TYPES...> &func ) {
functor = func;
}
RES_TYPE call_back( ARG_TYPES... args ) {
return functor.func_( args... );
}
};
int main() {
Functor<int, int, int> func;
auto lambda = []( int a, int b ) { return a + b; };
func.func_ = lambda;
Driver<int, int, int> driver;
driver.register_callback( func );
int a = 3;
int b = 5;
std::cout << driver.call_back( a, b ) << '\n';
std::cout << driver.call_back( 7, 5 ) << '\n';
Functor<void, std::string, std::string> func2;
auto lambda2 = []( std::string str1, std::string str2 ) {
str1 = str1 + " " + str2;
std::cout << str1 << '\n';
};
Driver <void, std::string, std::string> driver2;
func2.func_ = lambda2;
std::string str1 = "Hello";
std::string str2 = "World";
driver2.register_callback( func2 );
driver2.call_back( str1, str2 );
driver2.call_back( "Generic", "Programming" );
return 0;
}
Expected Outputs:
8
12
Hello World
Generic Programming
Actual Outputs:
8
12
Hello World
Generic Programming
Progam Exit:
Code (0)
您正试图在名为 callback_
的 Functor
实例上调用 operator()(int, int)
。相反,您需要将此结构的数据成员命名为 call_back
。像这样:
RES_TYPE call_back( ARG_TYPES... args ) {
return callback_.call_back( args... );
}
我这里有几个 classes,第一个是存储 std::function
类型的 class。
template<typename RES_TYPE, typename... ARG_TYPES>
struct Functor {
std::function<RES_TYPE( ARG_TYPES... )> call_back;
};
我有另一个 class,它将从函数对象、函数指针或 lambda 中注册一个传入函数,并存储上述 class 的实例,并具有另一个将调用的成员函数它。
template<typename RES_TYPE, typename... ARG_TYPES>
class Driver {
private:
Functor<RES_TYPE, ARG_TYPES...> callback_;
public:
Driver() = default;
~Driver() = default;
void register_callback( const Functor<RES_TYPE, ARG_TYPES...> &func ) {
callback_ = func;
}
RES_TYPE call_back( ARG_TYPES... args ) {
return callback_( args... );
}
};
我正在努力使语法正确到我试图在尝试调用它时传递函数值的位置。我的主要看起来像这样:
int main() {
Functor<int, int, int> func;
auto lambda = []( int a, int b ) { return a + b; };
func.call_back = lambda;
Driver<int, int, int> driver;
driver.register_callback( func );
std::cout << driver.call_back( 3, 5 ) << '\n';
return 0;
}
我似乎无法理解语法中缺少的内容。我已经尝试了其他各种方法,但是使用当前设置,我从 Visual Studio 2017 CE:
得到了这个编译器错误1>------ Build started: Project: Temp, Configuration: Debug Win32 ------
1>main.cpp
1>c:\...\main.cpp(62): error C2064: term does not evaluate to a function taking 2 arguments
1>c:\...\main.cpp(62): note: while compiling class template member function 'RES_TYPE Driver<RES_TYPE,int,int>::call_back(int,int)'
1> with
1> [
1> RES_TYPE=int
1> ]
1>c:\...\main.cpp(77): note: see reference to function template instantiation 'RES_TYPE Driver<RES_TYPE,int,int>::call_back(int,int)' being compiled
1> with
1> [
1> RES_TYPE=int
1> ]
1>c:\...\main.cpp(75): note: see reference to class template instantiation 'Driver<int,int,int>' being compiled
1>Done building project "Temp.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
我知道编译器在告诉我什么,但我似乎无法获得正确的语法来存储此 lambda,然后再调用它。我试图让这些 classes 尽可能通用,以便它可以接受 lambda、函数对象或函数指针。
解决方案
我的代码现在看起来像这样并且工作正常!
template<typename RES_TYPE, typename... ARG_TYPES>
struct Functor {
std::function<RES_TYPE( ARG_TYPES... )> func_;
};
template<typename RES_TYPE, typename... ARG_TYPES>
class Driver {
private:
Functor<RES_TYPE, ARG_TYPES...> functor;
public:
Driver() = default;
~Driver() = default;
void register_callback( const Functor<RES_TYPE, ARG_TYPES...> &func ) {
functor = func;
}
RES_TYPE call_back( ARG_TYPES... args ) {
return functor.func_( args... );
}
};
int main() {
Functor<int, int, int> func;
auto lambda = []( int a, int b ) { return a + b; };
func.func_ = lambda;
Driver<int, int, int> driver;
driver.register_callback( func );
int a = 3;
int b = 5;
std::cout << driver.call_back( a, b ) << '\n';
std::cout << driver.call_back( 7, 5 ) << '\n';
Functor<void, std::string, std::string> func2;
auto lambda2 = []( std::string str1, std::string str2 ) {
str1 = str1 + " " + str2;
std::cout << str1 << '\n';
};
Driver <void, std::string, std::string> driver2;
func2.func_ = lambda2;
std::string str1 = "Hello";
std::string str2 = "World";
driver2.register_callback( func2 );
driver2.call_back( str1, str2 );
driver2.call_back( "Generic", "Programming" );
return 0;
}
Expected Outputs:
8 12 Hello World Generic Programming
Actual Outputs:
8 12 Hello World Generic Programming
Progam Exit:
Code (0)
您正试图在名为 callback_
的 Functor
实例上调用 operator()(int, int)
。相反,您需要将此结构的数据成员命名为 call_back
。像这样:
RES_TYPE call_back( ARG_TYPES... args ) {
return callback_.call_back( args... );
}