问题描述
我试图使用 tbb :: parallel_sort
同时对2个数组排序。这里的Intel文档说明了 对迭代器和序列的要求与std :: sort相同。
。这似乎不是这样的。我的自定义迭代器与 std :: sort
完美地工作,但产生一个编译错误与 tbb :: parallel_sort
。请参阅下面的代码:
I am trying to use tbb::parallel_sort
to sort 2 arrays at the same time. Intel's documentation here says https://software.intel.com/en-us/node/506167 The requirements on the iterator and sequence are the same as for std::sort.
. This doesn't seem to be the case. My custom iterator works perfectly fine with std::sort
but produces a compilation error with tbb::parallel_sort
. Please see the code bellow:
int main()//needs boost and tbb to compile
{
int values_size = 6;
int nums1[] = {5, 8, 7, 89, 56, 4};
int nums2[] = {2, 1, 1, 4, 9, 2};
//WORKS!
std::sort(do_dual_sort.make_iter(nums1, nums2),
do_dual_sort.make_iter(nums1+values_size, nums2+values_size),
do_dual_sort.make_comp_desc(nums1, nums2));
//DOESN'T COMPILE
tbb::parallel_sort(do_dual_sort.make_iter(nums1, nums2),
do_dual_sort.make_iter(nums1+values_size, nums2+values_size),
do_dual_sort.make_comp_desc(nums1, nums2));
for(unsigned int i = 0; i < values_size; i++) cout << "nums1[" << i << "] " << nums1[i] << " | nums2[" << i << "] " << nums2[i] << "\n";
return 0;
}
class dual_sort
{
public:
template <class T, class T2>
struct helper_type {
public:
typedef boost::tuple<typename iterator_traits<T>::value_type, typename iterator_traits<T2>::value_type> value_type;
typedef boost::tuple<typename iterator_traits<T>::value_type&, typename iterator_traits<T2>::value_type&> ref_type;
};
template <typename T1, typename T2>
class dual_iterator : public boost::iterator_facade<dual_iterator<T1, T2>,
typename helper_type<T1, T2>::value_type,
boost::random_access_traversal_tag,
typename helper_type<T1, T2>::ref_type> {
public:
explicit dual_iterator(T1 iter1, T2 iter2) : mIter1(iter1), mIter2(iter2) {}
typedef typename iterator_traits<T1>::difference_type difference_type;
private:
void increment() { ++mIter1; ++mIter2; }
void decrement() { --mIter1; --mIter2; }
bool equal(dual_iterator const& other) const { return mIter1 == other.mIter1; }
typename helper_type<T1, T2>::ref_type dereference() const { return (typename helper_type<T1, T2>::ref_type(*mIter1, *mIter2)); }
difference_type distance_to(dual_iterator const& other) const { return other.mIter1 - mIter1; }
void advance(difference_type n) { mIter1 += n; mIter2 += n; }
T1 mIter1;
T2 mIter2;
friend class boost::iterator_core_access;
};
template <typename T1, typename T2>
dual_iterator<T1, T2> make_iter(T1 t1, T2 t2) { return dual_iterator<T1, T2>(t1, t2); }
template <class T1, class T2> struct iter_comp_desc {
typedef typename helper_type<T1, T2>::value_type T;
bool operator()(const T& t1, const T& t2) const { return get<0>(t1) > get<0>(t2); }
bool operator()(const char*& t1, const char*& t2) const { return strcmp(get<0>(t1), get<0>(t2)) == 1; }
};
template <class T1, class T2> iter_comp_desc<T1, T2> make_comp_desc(T1 t1, T2 t2) { return iter_comp_desc<T1, T2>(); }
} do_dual_sort;
我得到的编译错误是:
error C2512: 'dual_sort::dual_iterator<T1,T2>' : no appropriate default constructor available
with
[
T1=int *,
T2=int *
]
tbb44_20150728oss\include\tbb/parallel_sort.h(201) : see reference to function template instantiation 'void tbb::internal::parallel_quick_sort<RandomAccessIterator,Compare>(RandomAccessIterator,RandomAccessIterator,const Compare &)' being compiled
with
[
RandomAccessIterator=dual_sort::dual_iterator<int *,int *>,
Compare=dual_sort::iter_comp_desc<int *,int *>
]
main.cpp(1125) : see reference to function template instantiation 'void tbb::parallel_sort<dual_sort::dual_iterator<T1,T2>,dual_sort::iter_comp_desc<T1,T2>>(RandomAccessIterator,RandomAccessIterator,const Compare &)' being compiled
with
[
T1=int *,
T2=int *,
RandomAccessIterator=dual_sort::dual_iterator<int *,int *>,
Compare=dual_sort::iter_comp_desc<int *,int *>
]
编辑:我使用的编译器是 Visual Studio 2012
。你可以尝试用 std
替换一些boost函数,使它在 g ++
上工作。
Edit: The compiler I used is Visual Studio 2012
. You can try to replace some boost functions with std
ones to get it work on g++
.
推荐答案
类quick_sort_range
在 tbb / parallel_sort.h
包含 RandomAccessIterator begin;
成员在其构造函数中进行复制初始化,并在其他构造函数中进行默认初始化和分配。因此,它需要默认和可复制构造和可分配的迭代器。
The class quick_sort_range
in tbb/parallel_sort.h
contains RandomAccessIterator begin;
member which is copy-initialized in one its constructor and default-initialized and then assigned in the other constructor. Thus it requires iterators which are default©-constructable and assignable.
因此,TBB文档不正确,声明了与 std :: sort
相同的要求,因为稍后需要随机访问迭代器,其中不需要是可分配的,而TBB实现需要版本< = 4.4。
So, the TBB documentation is not correct claiming the same requirements as std::sort
since the later requires just random-access iterators which are not required to be assignable while TBB implementation requires it for versions <= 4.4.
默认可构造和可分配的需求可以是固定的,但是移动或可复制构造可能仍然存在(使文档中的声明正确)。您可以在上报告此问题。
The default-constructable and assignable requirements can be fixed but move or copy-constructable will likely remain (making the claim in the documentation correct). You can report this issue on TBB Forum.
您可以安全地将默认和复制构造函数和赋值运算符添加到代码中,以使用 tbb :: parallel_sort
You can safely add default© constructors and assignment operator to your code to compile it with tbb::parallel_sort
as far as I can see.
以下是您的代码片段的在线编译器:
Here is the online compiler with your snippet: http://coliru.stacked-crooked.com/a/47dafd091d36a9c4
这篇关于自定义迭代器与std :: sort工作,但不与tbb :: parallel_sort?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!