繁体   English   中英

c ++:错误:'class std :: result_of中没有名为'type'的类型

[英]c++: error: no type named ‘type’ in ‘class std::result_of<void (*(std::unordered_map

以下是使用两个线程插入哈希表进行测试的简单程序。 对于测试,不使用锁定。

#include <iostream>
#include <unordered_map>
#include <thread>

using namespace std;

void thread_add(unordered_map<int, int>& ht, int from, int to)
{
    for(int i = from; i <= to; ++i)
        ht.insert(unordered_map<int, int>::value_type(i, 0));
}

void test()
{
    unordered_map<int, int> ht;
    thread t[2];

    t[0] = thread(thread_add, ht, 0, 9);
    t[1] = thread(thread_add, ht, 10, 19);

    t[0].join();
    t[1].join();

    std::cout << "size: " << ht.size() << std::endl;
}

int main()
{
    test();
    return 0;
}

但是,编译时会出错。

$ g++ -std=c++11 -pthread test.cpp
...
/usr/include/c++/4.8.2/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of<void (*(std::unordered_map<int, int>, int, int))(std::unordered_map<int, int>&, int, int)>’
       typedef typename result_of<_Callable(_Args...)>::type result_type;
...

花了一段时间,但仍然无法纠正它。 谢谢。

我可以使用MSVC2013成功编译您的代码。 但是, thread()可以将其参数的副本传递给新线程。 这意味着如果你的代码会在你的编译器上编译,那么每个线程都会使用自己的ht副本运行,所以在最后, mainht将是空的。

GCC不会使用这个奇怪的消息进行编译。 你可以通过使用带线程的引用包装器来摆脱它:

t[0] = thread(thread_add, std::ref(ht), 0, 9);
t[1] = thread(thread_add, std::ref(ht), 10, 19);

这将成功编译。 并且线程使用的每个引用都将引用相同的对象。

但是,很有可能会出现运行时错误或意外结果。 这是因为两个线程正在尝试插入ht unordered_map不是线程安全的,因此这些竞争条件可能会导致ht达到不稳定状态(即UB,即潜在的segfault)。

为了使其正常运行,您必须保护您的concurent访问:

#include <mutex>
...
mutex mtx;   // to protect against concurent access

void thread_add(unordered_map<int, int>& ht, int from, int to)
{
    for (int i = from; i <= to; ++i) {
        std::lock_guard<std::mutex> lck(mtx);  // protect statements until end of block agains concurent access
        ht.insert(unordered_map<int, int>::value_type(i, 0));
    }
}

这个错误确实很神秘,但问题是thread_add通过引用获取它的第一个参数,但是你按值传递它。 这会导致仿函数类型推断错误。 如果你想通过引用传递一些东西,比如std::bindstd::thread的main函数,你需要使用引用包装器( std::ref ):

void test()
{
    // ...

    t[0] = thread(thread_add, std::ref(ht), 0, 9);
    t[1] = thread(thread_add, std::ref(ht), 10, 19);

    // ...
}

[实例]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM