简体   繁体   English

使用std :: async时,C ++“无法推断出模板参数”

[英]C++ “Could not deduce template argument” when using std::async

I'm quite new to C++ and programming in general. 一般来说,我对C ++和编程还是很陌生。 To practise, I made a sorting algorithm similar to mergesort. 实际上,我制定了一种类似于mergesort的排序算法。 Then I tried to make it multi-threaded. 然后,我尝试使其成为多线程。

std::future<T*> first = std::async(std::launch::async, &mergesort, temp1, temp1size);
    std::future<T*> second = std::async(std::launch::async, &mergesort, temp2, temp2size);
    temp1 = first.get();
    temp2 = second.get();

But it seems my compiler can't decide which template to use as I get the same error twice. 但是似乎我的编译器无法确定要使用哪个模板,因为两次出现相同的错误。

Error   1   error C2783: 'std::future<result_of<enable_if<std::_Is_launch_type<_Fty>::value,_Fty>::type(_ArgTypes...)>::type> std::async(_Policy_type,_Fty &&,_ArgTypes &&...)' : could not deduce template argument for '_Fty'
Error   2   error C2784: 'std::future<result_of<enable_if<!std::_Is_launch_type<decay<_Ty>::type>::value,_Fty>::type(_ArgTypes...)>::type> std::async(_Fty &&,_ArgTypes &&...)' : could not deduce template argument for '_Fty &&' from 'std::launch'

The errors lead me to believe that std::async is overloaded with two different templates, one for a specified policy and one for an unspecified, and the compiler fails to select the correct one (I'm using Visual Studio Express 2013). 这些错误使我相信std :: async重载了两个不同的模板,一个用于指定的策略,一个用于未指定的模板,并且编译器无法选择正确的模板(我使用的是Visual Studio Express 2013)。 So how do I specify to the compiler the appropriate template? 那么,如何为编译器指定适当的模板? (doing std::future<T*> second = std::async<std::launch::async>(&mergesort, temp2, temp2size); doesn't seem to work, I get invalid template argument, type expected). (做std::future<T*> second = std::async<std::launch::async>(&mergesort, temp2, temp2size);似乎不起作用,我得到了无效的模板参数,键入预期的)。 And is there a better way to do this all-together? 有没有更好的方法可以完全做到这一点? Thanks! 谢谢!

You need to specify the template parameter for mergesort . 您需要为mergesort指定模板参数。 Async isn't going to be smart enough to figure it out on its own. 异步不够聪明,无法自行解决。 An example that is iterator based appears below. 下面是一个基于迭代器的示例。 It also utilizes the current active thread as a recursion point rather than burning a thread handle waiting on two other threads. 它还将当前活动线程用作递归点,而不是燃烧等待其他两个线程的线程句柄。

I warn you, there are better ways to do this, but tuning this may suffice your needs. 我警告您,有更好的方法可以做到这一点,但对此进行调整可能就可以满足您的需求。

#include <iostream>
#include <algorithm>
#include <vector>
#include <thread>
#include <future>
#include <random>
#include <atomic>

static std::atomic_uint_fast64_t n_threads = ATOMIC_VAR_INIT(0);

template<typename Iter>
void mergesort(Iter begin, Iter end)
{
    auto len = std::distance(begin,end);

    if (len <= 16*1024) // 16K segments defer to std::sort
    {
        std::sort(begin,end);
        return;
    }

    Iter mid = std::next(begin,len/2);

    // start lower parttion async
    auto ft = std::async(std::launch::async, mergesort<Iter>, begin, mid);
    ++n_threads;

    // use this thread for the high-parition.
    mergesort(mid, end);

    // wait on results, then merge in-place
    ft.wait();
    std::inplace_merge(begin, mid, end);
}

int main()
{
    std::random_device rd;
    std::mt19937 rng(rd());
    std::uniform_int_distribution<> dist(1,100);

    std::vector<int> data;
    data.reserve(1024*1024*16);
    std::generate_n(std::back_inserter(data), data.capacity(),
                    [&](){ return dist(rng); });

    mergesort(data.begin(), data.end());
    std::cout << "threads: " << n_threads << '\n';
}

Output 产量

threads: 1023

You'll have to trust me that the end vector is sorted. 您必须相信我,最终向量已排序。 not going to dump 16MB of values into this answer. 不会将16MB的值转储到此答案中。

Notes: This was compiled and tested using clang 3.3 on an Mac and ran without issue. 注意:此文件在Mac上使用clang 3.3进行了编译和测试,并且没有问题。 My gcc 4.7.2 unfortunately is brain-dead, as it tosses cookies in a shared-count abort, but I don't have high confidence in the libstdc++ or VM on which it is housed. 不幸的是,我的gcc 4.7.2死了,因为它会在共享计数中止时抛出cookie,但是我对它所在的libstdc ++或VM并不抱有很高的信心。

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

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