13

boost::bindをテストするための簡単な例を書くだけです。テンプレートメンバー関数をインスタンス化するために使用しますが、g++4.6.0ではコンパイルされません。何が問題なのかわかりません。コードは次のとおりです。

#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

誰かがこれを説明するのを手伝ってもらえますか?最初のインスタンス化がOKで、2番目のインスタンス化がコンパイルエラーを引き起こすのはなぜですか?

4

1 に答える 1

14

ここに関係する(非自明の)機能があり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::bindfunc2あなたが意味したのは「実行し"Hello"、次に結果に対して実行する」ことであると想定していますfunc1。これにより、より興味深い部分機能の適用が可能になります。

プログラムには、次のような式があります。

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

したがって、引数boost::bindを実行する方法を理解しようとします。DerivedFinishAction::Incこれにより、その結果をに渡すことができDerivedFinishAction::BindFunc<...>ます。ただしDerivedFinishAction::Inc、voidを返します。これは、に渡すことはできませんDerivedFinishAction::BindFunc<...>。したがって、コンパイラエラーが発生します。

/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
...
于 2012-05-15T02:39:50.033 に答える