简体   繁体   中英

Call of boost::compute::sort() with zip iterators delivers build errors

I have a problem building a program that makes use of the Boost.Compute library. I use two zip_iterator s consisting out of a tuple of two float iterators each to sort two float-vectors with the boost::compute::sort() function. My code (both compute::vector s have been filled with float values before):

typedef compute::vector<float>::iterator Float_Iterator;
typedef boost::tuple<Float_Iterator, Float_Iterator> Sort_Tuple;
typedef compute::zip_iterator<Sort_Tuple> Sort_Iterator;

Sort_Iterator first_sort = compute::make_zip_iterator
(boost::make_tuple(d_x.begin(), d_y.begin()));
Sort_Iterator last_sort = compute::make_zip_iterator
(boost::make_tuple(d_x.end(), d_y.end()));

BOOST_COMPUTE_FUNCTION(bool, compare, (const boost::tuple<float, float> p1, const boost::tuple<float, float> p2),
{
    return boost_tuple_get(p1, 0) < boost_tuple_get(p2, 0);
}
);

compute::sort(first_sort, last_sort, compare, queue);

When compiling this, I receive:

error C2782: 'void   boost::compute::detail::dispatch_merge_blocks(Iterator,Iterator,Compare,size_t,c onst size_t,const size_t,const size_t,boost::compute::command_queue &)' :   **template parameter 'Iterator' is ambiguous**
          c:\local\boost_1_62_0\boost\compute\algorithm\detail\merge_sort_on_cpu.hpp(129)     : see declaration of 'boost::compute::detail::dispatch_merge_blocks'
          could be **'Sort_Iterator'
 or       'boost::compute::buffer_iterator<T>'**
          with
          [
              T=value_type
          ]

As you can see in my code, I call the function with two Sort_Iterator s I have declared before. Both arguments have the same type, so why should the compiler assume any ambiguity? I don't get this.

However, if I try to explicitly type cast the function arguments, like

compute::sort((Sort_Iterator)first_sort, (Sort_Iterator)last_sort, compare,    queue);

the latter part of the error message changes to:

could be **'boost::compute::zip_iterator<Sort_Tuple>'
or       'boost::compute::buffer_iterator<T>'**
with
[
     T=value_type
]

Even if your code compiled, you wouldn't be able to sort zip iterators: they are read-only. You must sort a vector of tuples instead.

Regarding the Iterator ambiguity, the compiler isn't referring to the types you are passing, but to the Iterator of some function much deeper in the call chain:

template<class Iterator, class Compare>
inline void dispatch_merge_blocks(Iterator first, Iterator result, /* ... /);

It is called this way:

dispatch_merge_blocks(first, temp.begin(), /* ... */);
dispatch_merge_blocks(temp.begin(), first, /* ... */);

Here, first is the Iterator you passed in, of type:

zip_iterator<tuple<buffer_iterator<float>, buffer_iterator<float>>>

And temp.begin() is...

typedef typename std::iterator_traits<Iterator>::value_type value_type;

// temporary buffer for merge result
vector<value_type> temp(count, context);

a vector<tuple<float, float>>::iterator (1) . The compiler sees two different types for the same template parameter, and hence deduction fails.

Additionally, further in the call chain appears the following function:

template<class Iterator, class Compare>
inline void merge_blocks(Iterator first, Iterator result, /* ... */)
{
    // dummy iterator as it's not sort by key
    Iterator dummy;
    merge_blocks(first, dummy, result, dummy, /* ... */);
}

Note the line: Iterator dummy; . That fails to compile because zip_iterator has no default constructor, so template instantiation fails and the whole thing fails to compile.

(1) : I am not entirely sure how value_type ends up being deduced as tuple<float, float> , and going through the endless layers of templates is giving me a mild headache, but this is what is happening, essentially.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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