【发布时间】:2014-09-30 21:02:22
【问题描述】:
我在看std::asynchere的例子,如下:
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <future>
template <typename RAIter>
int parallel_sum(RAIter beg, RAIter end)
{
auto len = std::distance(beg, end);
if(len < 1000)
return std::accumulate(beg, end, 0);
RAIter mid = beg + len/2;
auto handle = std::async(std::launch::async,
parallel_sum<RAIter>, mid, end);
int sum = parallel_sum(beg, mid);
return sum + handle.get();
}
int main()
{
std::vector<int> v(10000, 1);
std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << '\n';
}
我尝试使用 Clang 3.4 的 Web 编译器对其进行编译,结果输出 The sum is 而不是预期的 The sum is 1000。
我复制了示例并使用以下命令在 Ubuntu 14.04.1 64 位上使用 clang 3.5-1ubuntu1 / gcc 4.8 编译:
clang++ -g main.cpp -std=c++1y -o out -pthread;
我收到以下错误:
main.cpp:15:19: error: no matching function for call to 'async'
auto handle = std::async(std::launch::async,
^~~~~~~~~~
main.cpp:24:35: note: in instantiation of function template specialization
'parallel_sum<__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> >
> >' requested here
std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << '\n';
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/future:1523:5: note:
candidate template ignored: substitution failure [with _Fn = int
(__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >,
__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >), _Args =
<__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &,
__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &>]:
function cannot return function type 'int (__gnu_cxx::__normal_iterator<int *,
std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int *,
std::vector<int, std::allocator<int> > >)'
async(launch __policy, _Fn&& __fn, _Args&&... __args)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/future:1543:5: note:
candidate template ignored: substitution failure [with _Fn = std::launch, _Args = <int
(__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >,
__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >),
__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &,
__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &>]: no
type named 'type' in 'std::result_of<std::launch (int
(*)(__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >,
__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >),
__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &,
__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &)>'
async(_Fn&& __fn, _Args&&... __args)
^
1 error generated.
make: *** [all] Error 1
这是 clang、gcc、libstdc++ 中的错误,还是我遗漏了什么?
【问题讨论】:
-
嗯。罪魁祸首在这里:
with _Fn = int (__gnu_cxx::__normal_iterator<..>, __gnu_cxx::__normal_iterator<..>)这应该是一个左值引用。好像扣法有问题。 -
好的,我把它归结为以下问题:
template<class T> void deduce(T&&) { /* print type T */ }。对于deduce(parallel_sum<int*>);,clang++ 推导出T == int(int*,int*),而g++ 推导出T == int(&)(int*,int*)。这会导致问题。 -
这看起来很像一个 clang++ 错误。如果函数不是函数模板特化,它会推导出左值引用。 Live example
-
作为一种解决方法,如果
async的参数是static_cast<decltype((parallel_sum<RAIter>))>(parallel_sum),clang 会编译:O
标签: c++ gcc c++11 clang libstdc++