2012-05-15 19 views
12

boost :: bindをテストする簡単な例を書いておきます。私はテンプレートメンバー関数をインスタンス化するためにそれを使用しますが、g ++ 4.6.0ではコンパイルされません。私は何が問題なのか分からない。 は、ここでは、コードです:boost :: bindはメンバーテンプレート関数でコンパイルされません

#include <boost/bind.hpp> 

struct Functor 
{ 
    void operator()() 
    { 

    } 
}; 

struct DerivedFinishAction 
{ 
    DerivedFinishAction() 
    {} 

    void Inc() 
    { 

    } 

    template <typename T> 
    void TmplFunc(T t) 
    { 
    (boost::bind(&DerivedFinishAction::BindFunc<T>, this , t))(); 
    } 

    template <typename T> 
    void BindFunc(T t) 
    { 
    t(); 
    } 

    void Func() 
    { 
    Functor f; 
    TmplFunc(f); // this is OK 
    TmplFunc(boost::bind(&DerivedFinishAction::Inc, this)); // compile error 
    } 
}; 

int main(int argc, char *argv[]) 
{ 

    return 0; 
} 

と、次のエラーが発生します++ G:

In file included from /usr/include/boost/bind.hpp:22:0, 
       from testBind.cpp:1: 
/usr/include/boost/bind/bind.hpp: In member function ‘void boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = boost::_mfi::mf1<void, DerivedFinishAction, boost::_bi::bind_t<void, boost::_mfi::mf0<void, DerivedFinishAction>, boost::_bi::list1<boost::_bi::value<DerivedFinishAction*> > > >, A = boost::_bi::list0, A1 = boost::_bi::value<DerivedFinishAction*>, A2 = boost::_bi::bind_t<void, boost::_mfi::mf0<void, DerivedFinishAction>, boost::_bi::list1<boost::_bi::value<DerivedFinishAction*> > >]’: 
/usr/include/boost/bind/bind_template.hpp:20:59: instantiated from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()() [with R = void, F = boost::_mfi::mf1<void, DerivedFinishAction, boost::_bi::bind_t<void, boost::_mfi::mf0<void, DerivedFinishAction>, boost::_bi::list1<boost::_bi::value<DerivedFinishAction*> > > >, L = boost::_bi::list2<boost::_bi::value<DerivedFinishAction*>, boost::_bi::bind_t<void, boost::_mfi::mf0<void, DerivedFinishAction>, boost::_bi::list1<boost::_bi::value<DerivedFinishAction*> > > >, boost::_bi::bind_t<R, F, L>::result_type = void]’ 
testBind.cpp:24:5: instantiated from ‘void DerivedFinishAction::TmplFunc(T) [with T = boost::_bi::bind_t<void, boost::_mfi::mf0<void, DerivedFinishAction>, boost::_bi::list1<boost::_bi::value<DerivedFinishAction*> > >]’ 
testBind.cpp:37:58: instantiated from here 
/usr/include/boost/bind/bind.hpp:313:9: error: invalid use of void expression 

誰がこれを説明するのに役立つことはできますか?第1のインスタンス化がOKで、第2のインスタンス化がコンパイルエラーの原因となるのはなぜですか?

+1

をこれは奇妙な..です –

+0

@SethCarnegie、15分、 XDのためだけです – chris

答えて

13

ここにはboost::bindの(明白でない)機能が含まれています。 http://www.boost.org/libs/bind/#nested_binds

あなたが書く場合:

void func1(int len) {return len+1;}; 
int func2(std::string str) {return str.length();}; 

assert(
    boost::bind(func1, boost::bind(func2, _1))("Hello") 
    == 6); 

boost::bindが何を意味する "結果にfunc1を実行し、"Hello"func2を実行する" であることを前提としています。これにより、より興味深い部分機能の適用が可能になる。あなたのプログラムで

、あなたがになる表現があります。

boost::bind(&DerivedFinishAction::BindFunc<...>, 
      this, 
      boost::bind(&DerivedFinishAction::Inc, this)) 

をそうboost::bindは、それがDerivedFinishAction::BindFunc<...>にその結果を渡すことができますので、その引数にDerivedFinishAction::Incを実行する方法を見つけ出すしようとします。しかしDerivedFinishAction::IncDerivedFinishAction::BindFunc<...>に渡すことができないvoidを返します。

/usr/include/boost/bind/bind.hpp:313:9: error: invalid use of void expression 

編集:したがって、あなたは、コンパイラのエラーを取得するドキュメントごとに、ご希望の動作を実現するためにprotectを使用することができます。

#include <boost/bind/protect.hpp> 
... 
TmplFunc(boost::protect(boost::bind(&DerivedFinishedAction::Inc, this))); // no longer an error 
... 
+0

'boost :: bind'のこの機能は' std :: bind'にも当てはまります。 – ildjarn

+0

解決策は素晴らしいです。ありがとう@マナグ – airekans

関連する問題