grpc & protobuf -- error: no type named 'type' in std::result_of<>
grpc & protobuf -- error: no type named 'type' in std::result_of<>
在我的程序中,我有一个 Master class(grpc 异步客户端),它将工作分发给所有 Worker(grpc 异步服务器),它通过一个名为 WorkerClient 的 class 来处理所有通信开销。
我的主人class试图设置一个(分离的)后台线程来等待服务器的响应,这就是我的困难所在。
我尝试过的一个策略是使我的 "AsyncComplete" 函数成为 WorkerClient class 的一部分(与最近涉及基于异步客户端-服务器 grpc 的程序的方法相同- grpc.io 上的欢迎教程),此方法的 class 详细信息如下。
class WorkerClient {
public:
WorkerClient(std::shared_ptr<grpc::Channel> channel);
void MapReduceWork(masterworker::WorkReq);
void AsyncComplete(void *, void *, int);
struct AsyncClientCall {
masterworker::WorkReply reply;
grpc::ClientContext context;
grpc::Status status;
std::unique_ptr<grpc::ClientAsyncResponseReader<masterworker::WorkReply>> rsp_reader;
};
std::mutex mtx;
std::unique_ptr<masterworker::MasterWorker::Stub> stub;
grpc::CompletionQueue cq;
masterworker::WorkReq work_req;
ClientState state;
};
class Master {
public:
Master(const MapReduceSpec&, const std::vector<FileShard>&);
......
private:
std::mutex mtx;
std::vector<FileShard> map_tasks;
std::vector<ReduceTask *> reduce_tasks;
std::vector<WorkerClient *> clients;
std::vector<std::string> m_interm_files;
std::vector<FileShard> shards;
MapReduceSpec mr_config;
};
这里是相关的功能详情
void WorkerClient::AsyncComplete(void *c, void *m, int client_num)
{
void *got_tag = NULL;
bool ok = false;
Master *mast = static_cast<Master*>(m);
WorkerClient *client = static_cast<WorkerClient*>(c);
cq.Next(&got_tag, &ok);
if (ok == false) {
fprintf(stderr, "cq->Next false!\n");
return;
}
......
}
创建线程的调用
void Master::RunMapJob()
{
// clients[] is of type WorkerClient
ptr = new std::thread(&WorkerClient::AsyncComplete,
static_cast<void*>(clients[i]), static_cast<void*>(this), i);
ptr->detach();
......
}
最后,问题本身
g++ -c master.cc -I../external/include -std=c++11 -g
In file included from /usr/include/c++/4.8/mutex:42:0,
from master.h:3,
from master.cc:2:
/usr/include/c++/4.8/functional: In instantiation of ‘struct std::_Bind_simple<std::_Mem_fn<void (WorkerClient::*)(void*, void*, int)>(void*, void*, int)>’:
/usr/include/c++/4.8/thread:137:47: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (WorkerClient::*)(void*, void*, int); _Args = {void*, void*, int&}]’
master.cc:223:65: required from here
/usr/include/c++/4.8/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<void (WorkerClient::*)(void*, void*, int)>(void*, void*, int)>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/include/c++/4.8/functional:1727:9: error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<void (WorkerClient::*)(void*, void*, int)>(void*, void*, int)>’
_M_invoke(_Index_tuple<_Indices...>)
^
make: *** [master.o] Error 1
到目前为止,我已经排除了一些显而易见的事情,比如没有使用 std::ref 将变量引用传递给线程函数,以及通常没有传递正确的线程函数参数。我还尝试使 AsyncComplete 成为静态独立函数,但这也不起作用,因为对 cq.Next 的调用(更改为 WorkerClient->cq.Next())抛出了 std::bad_alloc 异常(由于 CompletionQueue 代码在幕后,无法找出其中之一)。
如果有帮助,我能够找到 /usr/include/c++/4.8/functional 行,该行似乎在编译期间被阻塞(下)
typedef typename result_of<_Callable(_Args...)>::type result_type;
谁能帮我解释编译失败的原因,以及正确的修复方法是什么样的?我刚开始在这里发布问题,所以欢迎提供反馈,我知道这很长,但我想确保我掌握了所有信息。
提前致谢。
[系统详细信息:ubuntu 14.04,protobufs 3.0,从源代码为 protobufs 3.0 构建的 grpc]
这一行是问题所在:
ptr = new std::thread(&WorkerClient::AsyncComplete,
static_cast<void*>(clients[i]), static_cast<void*>(this), i)
std::thread
的构造函数接受一个仿函数和参数。您提供了 &WorkerClient::AsyncComplete
而没有给它一个 WorkerClient
的实例。我猜 clients[i]
中实际上包含一个客户端。如果你尝试
ptr = new std::thread(std::bind(&WorkerClient::AsyncComplete, clients[i], static_cast<void*>(clients[i]), static_cast<void*>(this), i))
它应该编译。
在我的程序中,我有一个 Master class(grpc 异步客户端),它将工作分发给所有 Worker(grpc 异步服务器),它通过一个名为 WorkerClient 的 class 来处理所有通信开销。
我的主人class试图设置一个(分离的)后台线程来等待服务器的响应,这就是我的困难所在。
我尝试过的一个策略是使我的 "AsyncComplete" 函数成为 WorkerClient class 的一部分(与最近涉及基于异步客户端-服务器 grpc 的程序的方法相同- grpc.io 上的欢迎教程),此方法的 class 详细信息如下。
class WorkerClient {
public:
WorkerClient(std::shared_ptr<grpc::Channel> channel);
void MapReduceWork(masterworker::WorkReq);
void AsyncComplete(void *, void *, int);
struct AsyncClientCall {
masterworker::WorkReply reply;
grpc::ClientContext context;
grpc::Status status;
std::unique_ptr<grpc::ClientAsyncResponseReader<masterworker::WorkReply>> rsp_reader;
};
std::mutex mtx;
std::unique_ptr<masterworker::MasterWorker::Stub> stub;
grpc::CompletionQueue cq;
masterworker::WorkReq work_req;
ClientState state;
};
class Master {
public:
Master(const MapReduceSpec&, const std::vector<FileShard>&);
......
private:
std::mutex mtx;
std::vector<FileShard> map_tasks;
std::vector<ReduceTask *> reduce_tasks;
std::vector<WorkerClient *> clients;
std::vector<std::string> m_interm_files;
std::vector<FileShard> shards;
MapReduceSpec mr_config;
};
这里是相关的功能详情
void WorkerClient::AsyncComplete(void *c, void *m, int client_num)
{
void *got_tag = NULL;
bool ok = false;
Master *mast = static_cast<Master*>(m);
WorkerClient *client = static_cast<WorkerClient*>(c);
cq.Next(&got_tag, &ok);
if (ok == false) {
fprintf(stderr, "cq->Next false!\n");
return;
}
......
}
创建线程的调用
void Master::RunMapJob()
{
// clients[] is of type WorkerClient
ptr = new std::thread(&WorkerClient::AsyncComplete,
static_cast<void*>(clients[i]), static_cast<void*>(this), i);
ptr->detach();
......
}
最后,问题本身
g++ -c master.cc -I../external/include -std=c++11 -g
In file included from /usr/include/c++/4.8/mutex:42:0,
from master.h:3,
from master.cc:2:
/usr/include/c++/4.8/functional: In instantiation of ‘struct std::_Bind_simple<std::_Mem_fn<void (WorkerClient::*)(void*, void*, int)>(void*, void*, int)>’:
/usr/include/c++/4.8/thread:137:47: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (WorkerClient::*)(void*, void*, int); _Args = {void*, void*, int&}]’
master.cc:223:65: required from here
/usr/include/c++/4.8/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<void (WorkerClient::*)(void*, void*, int)>(void*, void*, int)>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/include/c++/4.8/functional:1727:9: error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<void (WorkerClient::*)(void*, void*, int)>(void*, void*, int)>’
_M_invoke(_Index_tuple<_Indices...>)
^
make: *** [master.o] Error 1
到目前为止,我已经排除了一些显而易见的事情,比如没有使用 std::ref 将变量引用传递给线程函数,以及通常没有传递正确的线程函数参数。我还尝试使 AsyncComplete 成为静态独立函数,但这也不起作用,因为对 cq.Next 的调用(更改为 WorkerClient->cq.Next())抛出了 std::bad_alloc 异常(由于 CompletionQueue 代码在幕后,无法找出其中之一)。
如果有帮助,我能够找到 /usr/include/c++/4.8/functional 行,该行似乎在编译期间被阻塞(下)
typedef typename result_of<_Callable(_Args...)>::type result_type;
谁能帮我解释编译失败的原因,以及正确的修复方法是什么样的?我刚开始在这里发布问题,所以欢迎提供反馈,我知道这很长,但我想确保我掌握了所有信息。
提前致谢。
[系统详细信息:ubuntu 14.04,protobufs 3.0,从源代码为 protobufs 3.0 构建的 grpc]
这一行是问题所在:
ptr = new std::thread(&WorkerClient::AsyncComplete,
static_cast<void*>(clients[i]), static_cast<void*>(this), i)
std::thread
的构造函数接受一个仿函数和参数。您提供了 &WorkerClient::AsyncComplete
而没有给它一个 WorkerClient
的实例。我猜 clients[i]
中实际上包含一个客户端。如果你尝试
ptr = new std::thread(std::bind(&WorkerClient::AsyncComplete, clients[i], static_cast<void*>(clients[i]), static_cast<void*>(this), i))
它应该编译。