我有一个带有成员函数f
的类,我用variadic模板和forward
包装它以创建另一个成员函数rf
(只需在{}的末尾添加一个特定的参数{1}}做一点点不同的事情)。然后,我通过f
包裹async_rf
来创建另一个成员函数rf
,但它不起作用。我尝试通过使用其他特定参数包装async
来制作async_rf
,并且它可以正常工作。
代码:
f
这是编译时的错误消息:
(铛)
#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;
}
(GCC)
$ 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.
是否有人可以提供有关其无效的详细信息?为什么编译器找不到正确的模板专业化?
答案 0 :(得分:2)
要求编译器通过提供给rf
的参数来推断async
的特化,这将要求它调查async
的实现,这有点太多了。
只需自己指定模板参数:
return std::async (&test::rf<Args...>, this, std::forward<Args>(args)...);
顺便说一句,您可能希望在任何地方将Args...
更改为Args&&...
,否则参数将按值传递。
答案 1 :(得分:0)
由于rf
是一个功能模板,因此您不能简单地将其传递给std::async
。首先,您必须指定其模板参数,这只是Args...
。所以你的功能看起来像是:
template<typename... Args>
std::future<void> async_rf(Args... args)
{
// doesn't work
return std::async (&test::rf<Args...>,this,std::forward<Args>(args)...);
// work
return std::async (&test::f, this, std::forward<Args>(args)..., 1);
}
虽然在该函数中有2个return语句可能不是你想要做的。