2016-11-17 4 views
3

Boost.Computeライブラリを使用するプログラムを構築する際に問題があります。 boost::compute::sort()関数を持つ2つのフロートベクトルをソートするために、それぞれ という2つのフロートイテレータのタプルからなる2つのzip_iteratorを使用します。 私のコード(両方compute::vector Sは前float値で満たされている):zipイテレータでboost :: compute :: sort()を呼び出すと、ビルドエラーが発生します

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); 

これをコンパイルし、私が受け取る:

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 
      ] 

あなたは私のコードで見ることができるように、私は関数を呼び出します2つ前に私が宣言したのはSort_Iteratorです。両方の引数に同じ型があるので、コンパイラはなぜあいまいさを取るべきですか?私はこれを取得しません。

私は明示的に

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

のようなエラーメッセージの後半に変わり、関数の引数をキャストに入力しようとした場合しかし、:あなたのコードがコンパイルされた場合でも

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

答えて

3

、あなたがwouldn zipイテレータを並べ替えることができる:それらは読み取り専用です。代わりにタプルのベクトルをソートする必要があります。 Iterator曖昧さについて

、コンパイラはを渡している種類に言及されていませんが、コールチェーンのより深いいくつかの機能のIteratorに:

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

それは、この方法と呼ばれています:ここでは

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

は、firstはタイプで、あなたが渡されたIteratorです:

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

そしてtemp.begin()です...

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

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

vector<tuple<float, float>>::iterator(1)。コンパイラは同じテンプレートパラメータに対して2つの異なる型を見るため、控除は失敗します。

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, /* ... */); 
} 

注ライン:Iterator dummy;

はさらに、さらに、コールチェーンに次の機能を表示されます。 zip_iteratorにはデフォルトのコンストラクタがないため、テンプレートのインスタンス化に失敗してコンパイルが失敗するため、コンパイルが失敗します。

(1):私はvalue_typetuple<float, float>として推測し、私に軽度の頭痛を与えているテンプレートの無限の層を通過してしまう方法が全くわからないが、これは基本的に、何が起こっているかです。

+0

ありがとうございました!しかし、1つの質問が残っています。なぜ、読み取り専用のzip_iteratorを渡すのが問題になるのでしょうか?私はzip_iteratorsをソートしたいのではありませんが、(iteratosの構造のタプルを介して)それらが指すフロートベクトルをソートします。したがって、zip_iterators自体の値はsort()中に変更するべきではありませんか? – Miray

+0

Boost Computeの[Zipイテレータ用のOpenCLコードジェネレータは現在実装されています](https://github.com/boostorg/compute/blob/master/include/boost/compute/iterator/zip_iterator.hpp#L107)残念ながら仕事からの譲渡。私はこれが固定され、どのような費用がかかるのだろうかと思います。 –

関連する問題