抱歉,如果这个问题没有任何意义,我没有太多的经验与模板。 我想做一个泛型函数,它可以在类中存储一个静态函数列表,然后执行它们。我还需要将对象的引用传递给每个函数以执行它们。我在没有使用模板的情况下实现了这一点
#ifndef _handle_connection
#define _handle_connection
#include <string>
#include <utility>
#include <vector>
#include <errno.h>
#include <iostream>
namespace handle_connection
{
class handleconnection
{
std::vector<std::pair<void *, int (*)(void *, std::string, int)>> funclist;
public:
//adds function to the list of function to excecute
//@param reference of the object
//@param : int (*func)(void* ,std::string,int) function
void use(void *object, int (*func)(void *context, std::string response, int new_socket))
{
funclist.push_back(std::make_pair(object, func));
}
//call
//@param : string response
//@param : int socket
int call(std::string response, int new_socket)
{
for (auto c : funclist)
{
//need to extract the type of the reference object T
if (c.second(c.first, response, new_socket) == 0) //code is incomplete
return 0;
}
return -1;
}
};
} // namespace handle_connection
#endif
class foo
{
std::string path = "it worked for foo";
public:
static int func(void *object, std::string text, int socket);
};
class bar
{
int num = 10;
std::string path = "it worked for bar";
public:
static int func(void *object, std::string text, int socket);
};
int foo::func(void *object, std::string text, int socket)
{
std::cout << static_cast<foo *>(object)->path;
return -1;
}
int bar::func(void *object, std::string text, int socket)
{
std::cout << static_cast<bar *>(object)->path;
return 0;
}
int main()
{
foo obj1;
bar obj2;
handle_connection::handleconnection connections;
connections.use(&obj1, foo::func);
connections.use(&obj2, bar::func);
connections.call("hello", 1);
}
但为此,我必须将对象的void指针传递给函数,并在定义中强制转换,但我不想这么做。
//not void pointer
template<class T>
void use(void *object, int (*func)(T *context, std::string response, int new_socket))
{
funclist.push_back(std::make_pair(object, func));
//need to store the type information of reference object( T)
//code is incomplete
// i need to store the variable T as well somehow
}
如果我对模板的理解不正确,有人能告诉我我想错了什么吗。
为了简化,您可以只使用std::function
并将回调包装为lambda的:
class handleconnection
{
std::vector<std::function<int(std::string const&, int)>> funclist;
public:
void use(std::function<int(std::string const&, int)> const& func) {
funclist.push_back(func);
}
int call(std::string const& response, int new_socket) {
for (auto& func : funclist) {
if (func(response, new_socket) == 0) {
return 0;
}
}
return -1;
}
};
int main() {
handleconnection c;
c.use([](std::string const& msg, int sock) {
std::cout << "Func 1: " << msg << ", " << sock << "\n";
return 1;
});
std::string some_object = "Some Object";
c.use([&some_object](std::string const& msg, int sock) {
std::cout << "Func 2: " << msg << ", " << sock << ", " << some_object << "\n";
return 1;
});
c.call("test", 123);
}
您可以捕获lambda的[]
子句中的任何对象,并在。。。 不需要传递t
,void*
或类似信息。