可变参数模板的C ++异步找不到正确的功能模板专业化 [英] C++ async with variadic template can not find correct function template specialization

查看:370
本文介绍了可变参数模板的C ++异步找不到正确的功能模板专业化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有成员函数 f 的类,我用可变参数模板和 forward 将其包装起来,以制作另一个成员函数 rf (只是在 f 的末尾添加一个特定的参数来做一些不同的事情).然后,我通过用 async 包装 rf 来制作另一个成员函数 async_rf ,但这是行不通的.我尝试通过用其他特定参数包装 f 来制作 async_rf ,并且它可以正常工作.

I have a class with a member function f, I wrap it by variadic template and forward to make another member function rf (just add a specific parameter at the end of f to do a little bit different thing). Then, I make another member function async_rf by wrapping rf with async, but it doesn't work. I try to make async_rf by wrapping f with additional specific parameter, and it works.

代码:

#include <future>         // std::async, std::future
#include <iostream>

class test {

public:

    void f(int tmp, bool reverse = 0)
    {
        std::cout << tmp << " | " << reverse << std::endl;
    }

    template<typename... Args>
    void rf(Args... args)
    {
        f(std::forward<Args>(args)..., 1);
    }

    template<typename... Args>
    std::future<void> async_rf(Args... args)
    {
        // doesn't work
        return std::async (&test::rf, this, std::forward<Args>(args)...);

        // work
        return std::async (&test::f, this, std::forward<Args>(args)..., 1);
    }

};


int main()
{
    test s;
    auto tmp = s.async_rf(10);
    tmp.get();
    return 0;
}

这是编译时的错误消息:

here is the error message at compile time :

(c声)

$ clang++ --version
clang version 3.6.1 (tags/RELEASE_361/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
$ clang++ -std=c++14 -Wall -lpthread src/test.cpp -o bin/test
src/test.cpp:23:16: error: no matching function for call to 'async'
        return std::async (&test::rf, this, std::forward<Args>(args)...);
               ^~~~~~~~~~
src/test.cpp:35:18: note: in instantiation of function template specialization 'test::async_rf<int>' requested here
    auto tmp = s.async_rf(10);
                 ^
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/5.1.0/../../../../include/c++/5.1.0/future:1723:5: note: candidate template
      ignored: couldn't infer template argument '_Fn'
    async(_Fn&& __fn, _Args&&... __args)
    ^
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/5.1.0/../../../../include/c++/5.1.0/future:1703:5: note: candidate template
      ignored: substitution failure [with _Fn = test *, _Args = <int>]: no type named 'type' in
      'std::result_of<test *(int)>'
    async(launch __policy, _Fn&& __fn, _Args&&... __args)
    ^
1 error generated.

(gcc)

$ g++ --version
g++ (GCC) 5.1.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ g++ -std=c++14 -Wall -lpthread src/test.cpp -o bin/test
src/test.cpp: In instantiation of ‘std::future<void> test::async_rf(Args ...) [with Args = {int}]’:
src/test.cpp:35:29:   required from here
src/test.cpp:23:27: error: no matching function for call to ‘async(<unresolved overloaded function type>, test*, int)’
         return std::async (&test::rf, this, std::forward<Args>(args)...);
                           ^
In file included from src/test.cpp:1:0:
/usr/include/c++/5.1.0/future:1703:5: note: candidate: template<class _Fn, class ... _Args> std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...)
     async(launch __policy, _Fn&& __fn, _Args&&... __args)
     ^
/usr/include/c++/5.1.0/future:1703:5: note:   template argument deduction/substitution failed:
src/test.cpp:23:27: note:   cannot convert ‘&((test*)this)->*test::rf’ (type ‘<unresolved overloaded function type>’) to type ‘std::launch’
         return std::async (&test::rf, this, std::forward<Args>(args)...);
                           ^
In file included from src/test.cpp:1:0:
/usr/include/c++/5.1.0/future:1723:5: note: candidate: template<class _Fn, class ... _Args> std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(_Fn&&, _Args&& ...)
     async(_Fn&& __fn, _Args&&... __args)
     ^
/usr/include/c++/5.1.0/future:1723:5: note:   template argument deduction/substitution failed:
src/test.cpp:23:27: note:   couldn't deduce template parameter ‘_Fn’
         return std::async (&test::rf, this, std::forward<Args>(args)...);
                           ^

有人能提供更多有关为什么它不起作用的详细信息吗?为什么编译器找不到正确的模板专业化?

Does anyone can provide more detail about why it doesn't work ? Why compiler can not find correct template specialization ?

推荐答案

要求编译器通过提供给 async 的参数来推断 rf 的特殊性,这需要它考虑一下 async 的实现有点过多.

Requiring the compiler to deduce specialization of rf by arguments provided to async would require it to look into the implementation of async which is a bit too much.

只需自己指定模板参数:

Just specify the template parameters yourself:

return std::async (&test::rf<Args...>, this, std::forward<Args>(args)...);

顺便说一句,您可能想在任何地方将 Args ... 更改为 Args& ... ,否则参数将按值传递.

BTW you may want to change Args... to Args&&... everywhere, otherwise the arguments are passed by value.

这篇关于可变参数模板的C ++异步找不到正确的功能模板专业化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆