1

lambda::bindを介してメンバーを呼び出したいと思います。残念ながら、同じ名前で返品タイプが異なる2人のメンバーがいます。lambda :: bindがメンバー関数呼び出しの正しいリターン型を推測するのを助ける方法はありますか?(バインドは明示的なリターンタイプの推論で正常に機能します)

#include <vector>
#include <iostream>
#include <algorithm>
#include <boost/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

using namespace std;
using namespace boost;

struct A
{
  A (const string & name) : m_name(name) {}

  string &        name ()         { return m_name; }
  const string &  name () const   { return m_name; }

  string m_name;
};

vector<A> av;

int main () 
{
  av.push_back (A ("some name"));

  // compiles fine
  find_if(av.begin(), av.end(), bind<const string &>(&A::name, _1) == "some name");

  // error: call of overloaded 'bind(<unresolved overloaded function type>, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >&)' is ambiguous
  find_if(av.begin(), av.end(), lambda::bind(&A::name, lambda::_1) == "some name");

  return 0;
}
4

2 に答える 2

1

ドキュメントについて

"次の例のように、bind式によって作成されたラムダファンクターのリターンタイプは、明示的に指定されたテンプレートパラメーターとして指定できます。

bind(target-function、bind-argument-list)」

したがって、boost:bindで行ったのと同じことを実行します。

  find_if(av.begin(), av.end(), lambda::bind<const string &>(&A::name, lambda::_1) == "some name");

PSはテストされていません

于 2010-04-30T15:43:52.047 に答える
1

さまざまな返品タイプは赤ニシンです。問題はメソッドのconstオーバーロードにあります(つまり、相対的な戻りタイプが何であっても同じ問題が発生します)。この問題はここここに文書化されており、戻り型で指定されたフォームを使用することは推奨される解決策ではありません(MSVCの一部のバージョンを除いてほとんどの場合機能します)。

問題は、オーバーロードされたメンバー関数(constオーバーロードまたはパラメーターオーバーロードのいずれか)のアドレスを取得することがあいまいであるため、いくつかの追加情報が必要になることです。

解決策は、関数ポインターをキャストすることです。これにより、オーバーロードされた関数のどれが必要かをコンパイラーに正確に知らせることができます。これを行う最もクリーンな方法は、関数ポインターの型をtypedefすることです。そうしないと、行が少し厄介になります。コードの例を次に示します(clean gcc 4.3.4をコンパイルします)。

#include <vector>
#include <iostream>
#include <algorithm>
#include <boost/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

using namespace std;
using namespace boost;

struct A
{
  A (const string & name) : m_name(name) {}

  string &        name ()         { return m_name; }
  const string &  name () const   { return m_name; }

  string m_name;
};

vector<A> av;

//function pointer for non-const version
typedef string& (A::*NameFuncType)(void);

//function pointer for const version
typedef const string& (A::*NameConstFuncType)(void) const;

int main () 
{
  av.push_back (A ("some name"));

  //'correct' way to call const version w/ boost::bind
  find_if(av.begin(), av.end(), 
    bind(static_cast<NameConstFuncType>(&A::name), _1) == "some name"
  );

  //call for non-const version w/ boost::lambda::bind
  find_if(av.begin(), av.end(), 
     lambda::bind(static_cast<NameFuncType>(&A::name), lambda::_1) == "some name"
  );

  return 0;
}
于 2010-05-19T01:11:06.673 に答える