我正在尝试使用C ++ 11中的多线程,我得到了一些奇怪的结果。我有以下代码,它运行得很好(tree_node
是一个自定义类)
#include <thread>
#include <mutex>
#include "cards.h"
mutex m;
//a function that prints the node and his children
void nodes_print(tree_node& a, std::streampos pos_nodo){
cout << a.player.suit << a.player.value << " ";
cout << a.versus.suit << a.versus.value << " ";
if(a.nodes>0){
for (int i=0; i<a.nodes; i++){
//children_nodes stores node's children
nodes_print(a.children_nodes[i], o.tellp());
}
}
else return;
}
void node_child(tree_node a){
m.lock();
cout << "thread " << this_thread::get_id();
a.children(); //a function member of class tree_node
nodes_print(a,0);
m.unlock();
}
int main(){
tree_node node_1;
thread t(node_child, node_1);
if(t.joinable()) t.join();
return 0;
}
我的问题是我需要函数node_child
才能获得对tree_node
的引用。但是当我尝试使用函数void node_child(tree_node& a)
调用线程时如下
tree_node node_1;
thread t(node_child, node_1);
if(t.joinable()) t.join();
我收到以下错误/usr/include/c++/4.9/functional:1665:61: error: no type named ‘type’ in ‘class std::result_of<void (*(tree_node))(tree_node&)>’
在互联网上搜索我发现了一个使用std::ref(node_1)
包装器解决此问题的帖子,但我想知道在收到该错误时会发生什么。在我之前发现的帖子中,问题与访问相同资源的更多线程有关,但由于我只有一个线程,因此无法将该案例与我的相关联。
编辑:在标题tree_node
中添加cards.h
的定义
class tree_node{
tree_node();//ctor
tree_node(const tree_node&);//copy ctor
tree_node(tree_node&&); //move ctor
tree_node& operator= (tree_node);//assignment with copy-swap idiom
cards * player;
cards * versus;
int * suits_player;
int * suits_versus;
tree_node * children_nodes;
void children();
}
我会尽快检查答案,然后快速通过检查
答案 0 :(得分:2)
问题是该函数通过左值引用获取参数。在内部,std::thread
使用std::decay
删除参数类型的引用。当这些类型转发到函数时,结果是将rvalue传递给引用,该引用失败。
你没有得到“无法将rvalue绑定到左值引用”错误的原因是因为在模板实例化期间,使用了std::result_of
,它通过在函数调用表达式上使用decltype
来推断返回类型。但是,该调用无效,因此type
中未定义result_of
。
来自cppreference:
无法调用
type
...仅在未评估的上下文中使用参数ArgTypes ...调用F时才定义(自C ++ 14起)。
F
(您的函数),因此永远不会定义type
,因此编译器会为缺少的type
定义提供错误。