2

次のコードがあります (MSVC9 でブースト 1.55 を使用):

struct pair_first_impl
{
   template<class TPair> struct result { typedef typename TPair::first_type type; };

   template<class TPair>
   typename TPair::first_type const& operator() (TPair const& pair) const
   {
      return pair.first;
   }

   template<class TPair>
   typename TPair::first_type& operator() (TPair& pair)
   {
      return pair.first;
   }
};

static phx::function<pair_first_impl> pair_first;

int test()
{
   std::map<int, std::string> mymap;
   std::find_if(mymap.begin(), mymap.end(), pair_first(_1) == 1);
}

pair_first_impl::result::typeに関して、次のようなコンパイラ エラーが発生します。

error C2825: 'TPair': must be a class or namespace when followed by '::'
see reference to class template instantiation 'pair_first_impl::result<TPair>' being compiled
        with
        [
            TPair=const pair_first_impl (std::pair<const int,std::string> )
        ]

何らかの理由で、型を直接TPairではなく、関数型 (?) をテンプレート引数に渡しているようです。std::pair

ここで私が間違っていることを理解するのを手伝ってくれる人はいますか?

4

3 に答える 3

1

間違ったプレースホルダーを使用しています_1。実際にフェニックス アクターであるものが必要です。

std::find_if(mymap.begin(), mymap.end(), pair_first(phx::placeholders::_1) == 1);

OTOH、あなたのファンクターには一貫性のないresult_typeプロトコルがあります。を使用すると、これはあなたを噛まないかもしれませんBOOST_SPIRIT_RESULT_OF_USE_DECLTYPE。を使用しないのはなぜbindですか?これにより、作業なしですべての控除が正しくなります。

using namespace phx::arg_names;

void test()
{
   std::map<int, std::string> mymap;

   using Pair = std::pair<const int, std::string>;
   std::find_if(mymap.begin(), mymap.end(), phx::bind(&Pair::first, arg1) == 1);
}

もちろん、必要に応じてペア タイプを検出することもできます。

フルコードLive On Coliru

#include <boost/phoenix.hpp>
#include <algorithm>
#include <map>

namespace phx = boost::phoenix;

struct pair_first_impl
{
   template<class TPair> struct result { typedef typename TPair::first_type const& type; };

   template<class TPair>
   typename TPair::first_type const& operator() (TPair const& pair) const {
      return pair.first;
   }

   template<class TPair>
   typename TPair::first_type& operator() (TPair& pair) {
      return pair.first;
   }
};

static phx::function<pair_first_impl> pair_first;


void test1()
{
   using phx::placeholders::_1;

   std::map<int, std::string> mymap;
   std::find_if(mymap.begin(), mymap.end(), pair_first(_1) == 1);
}

void test2()
{
   using Pair = std::pair<const int, std::string>;
   using namespace phx::arg_names;

   std::map<int, std::string> mymap;
   std::find_if(mymap.begin(), mymap.end(), phx::bind(&Pair::first, arg1) == 1);
}

void test3()
{
   std::map<int, std::string> mymap;
   using Pair = decltype(mymap)::value_type;
   using namespace phx::arg_names;

   std::find_if(mymap.begin(), mymap.end(), phx::bind(&Pair::first, arg1) == 1);
}

int main()
{
    test1();
    test2();
    test3();
}
于 2014-03-23T19:53:19.150 に答える