试验多线程

时间:2016-02-26 20:01:14

标签: c++ multithreading c++11 reference

我正在尝试使用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();

}

我会尽快检查答案,然后快速通过检查

1 个答案:

答案 0 :(得分:2)

问题是该函数通过左值引用获取参数。在内部,std::thread使用std::decay删除参数类型的引用。当这些类型转发到函数时,结果是将rvalue传递给引用,该引用失败。

你没有得到“无法将rvalue绑定到左值引用”错误的原因是因为在模板实例化期间,使用了std::result_of,它通过在函数调用表达式上使用decltype来推断返回类型。但是,该调用无效,因此type中未定义result_of

来自cppreference

  

type ...仅在未评估的上下文中使用参数ArgTypes ...调用F时才定义(自C ++ 14起)。

无法调用

F(您的函数),因此永远不会定义type,因此编译器会为缺少的type定义提供错误。