2011-12-15 18 views
2
私は機能をエイリアシング問題を抱えています

boost::make_iterator_rangeboost :: make_iterator_rangeのエイリアスは可能ですか?

(私は、この特定のライブラリが将来的に標準に採用された場合などには、エイリアスの後ろにブーストを非表示にしたいと思います。)

どのような方法があり、これが可能です働くことができますか?

#include <boost/range/iterator_range.hpp> 

void Foo() 
{ 
} 

template< typename T > 
void Bar() 
{ } 

template< typename T > 
void Bar(char c) 
{ } 

void (&FooAlias)() = Foo;   // ok 
void (&BarAlias)() = Bar<int>;  // ok 

// boost::iterator_range<const size_t*> (&MakeIterRangeAlias)(const size_t*,const size_t*) = 
// boost::make_iterator_range<const size_t*>; // not ok 

int main(int argc, char** argv) 
{ 
    const size_t v[] = { 3, 5, 1, 5, 29, 15 }; 

    boost::iterator_range<const size_t*> r 
     = boost::make_iterator_range(std::begin(v), std::end(v)); // want to alias this 

    return 0; 
} 

エラーメッセージは次のとおりです。

関数ポインタを使用して
In file included from /usr/include/boost/iterator/iterator_categories.hpp:15:0, 
       from /usr/include/boost/iterator/detail/facade_iterator_category.hpp:7, 
       from /usr/include/boost/iterator/iterator_facade.hpp:14, 
       from /usr/include/boost/range/iterator_range_core.hpp:23, 
       from /usr/include/boost/range/iterator_range.hpp:13, 
       from sandbox.cpp:2: 
/usr/include/boost/mpl/eval_if.hpp: In instantiation of ‘boost::mpl::eval_if_c<true, boost::range_const_iterator<const long unsigned int*>, boost::range_mutable_iterator<const long unsigned int* const> >’: 
/usr/include/boost/range/iterator.hpp:63:63: instantiated from ‘boost::range_iterator<const long unsigned int* const>’ 
sandbox.cpp:20:10: instantiated from here 
/usr/include/boost/mpl/eval_if.hpp:60:31: error: no type named ‘type’ in ‘boost::mpl::eval_if_c<true, boost::range_const_iterator<const long unsigned int*>, boost::range_mutable_iterator<const long unsigned int* const> >::f_ {aka struct boost::range_const_iterator<const long unsigned int*>}’ 
/usr/include/boost/mpl/eval_if.hpp: In instantiation of ‘boost::mpl::eval_if_c<false, boost::range_const_iterator<const long unsigned int*>, boost::range_mutable_iterator<const long unsigned int*> >’: 
/usr/include/boost/range/iterator.hpp:63:63: instantiated from ‘boost::range_iterator<const long unsigned int*>’ 
sandbox.cpp:20:10: instantiated from here 
/usr/include/boost/mpl/eval_if.hpp:60:31: error: no type named ‘type’ in ‘boost::mpl::eval_if_c<false, boost::range_const_iterator<const long unsigned int*>, boost::range_mutable_iterator<const long unsigned int*> >::f_ {aka struct boost::range_mutable_iterator<const long unsigned int*>}’ 
sandbox.cpp:20:10: error: invalid initialization of non-const reference of type ‘void (&)(const size_t*, const size_t*) {aka void (&)(const long unsigned int*, const long unsigned int*)}’ from an rvalue of type ‘<unresolved overloaded function type>’ 
make: *** [sandbox] Error 1 
+2

私が見る最初の問題は、エイリアスの戻り値の型が間違っていることです( 'boost :: iterator_range 'で、 'void'ではなく)。 – Mankarse

+1

'make_iterator_range'の第2引数は'&v [n] 'でなければなりません。最後の要素の後の要素を指すはずです。 [C++ 11]というタグが付いているので、 'std :: begin'と' 'std :: end'(http://en.cppreference.com/w/cpp/iterator/end)を使用しないでください「n」を計算しなければならない。 – kennytm

+0

@Mankarse +1良い点:OP変更 – kfmfe04

答えて

5

は、関数の別名次善の方法です。これは元のものほど柔軟ではなく(テンプレートではありません)、関数の正確なシグネチャを知る必要があります。これは安定している場合とそうでない場合があります。
代わりにこのアプローチを試してください。エイリアスは、元の正確な署名をサポートしていますあなたの部分のほとんどない仕事で

template< typename ... Args > 
auto MakeIterRangeAlias(Args&& ... args) -> decltype(/* copy return line here */) 
{ 
    return boost::make_iterator_range(std::forward<Args>(args)...); 
} 

。劇的に変化しても、あなたはまだ設定されています。さらに、関数ポインタのアプローチとは異なり、オプティマイザは、ランタイムオーバーヘッドがないように、MakeIterRangeAliasを自明にインライン化することができます。

+0

@ deft-code偉大な提案、しかし私はそれが動作するように問題を抱えています。 decltype()を記入した後でも、テンプレートパラメータでTを取り出すとコンパイルされますが、MakeIterRangeAliasの呼び出しは正しくバインドされません。 gccを使用しています。4.6.1 – kfmfe04

+1

@ kfmfe04:申し訳ありませんが、コンパイルせずにコードを送信するとどうなりますか?ここでは、代わりに 'std :: make_pair'を使用するコンセプトの実証があります。[ideone.com/XVTxa(http://ideone.com/XVTxa) –

+0

@ deft-code - woohooバリデーショナルなテンプレートにも – kfmfe04

関連する問題