C++ 什么';我的boost-phoenix函数有什么问题?

C++ 什么';我的boost-phoenix函数有什么问题?,c++,boost,boost-phoenix,C++,Boost,Boost Phoenix,我有以下代码(在MSVC9上使用boost 1.55): 出于某种原因,它看起来像是将函数类型(?)传递到我的TPair模板参数中,而不是直接传递到std::pair类型中 有人能帮我找出我做错了什么吗?这并不能回答您的问题,但它提供了一个基于现有实现的解决方案:(未测试的代码) 这并不能回答您的问题,但它提供了一种基于现有实现的变通方法:(未测试的代码) 您使用了错误的占位符\u 1。你需要一个真正的凤凰演员: std::find_if(mymap.begin(), mymap.end(),

我有以下代码(在MSVC9上使用boost 1.55):

出于某种原因,它看起来像是将函数类型(?)传递到我的
TPair
模板参数中,而不是直接传递到
std::pair
类型中


有人能帮我找出我做错了什么吗?

这并不能回答您的问题,但它提供了一个基于现有实现的解决方案:(未测试的代码)


这并不能回答您的问题,但它提供了一种基于现有实现的变通方法:(未测试的代码)


您使用了错误的占位符
\u 1
。你需要一个真正的凤凰演员:

std::find_if(mymap.begin(), mymap.end(), pair_first(phx::placeholders::_1) == 1);
OTOH,你的函子有不一致的
结果类型
协议。当您使用
BOOST\u SPIRIT\u RESULT\u OF\u use\u DECLTYPE
时,这可能不会影响您。为什么不直接使用
绑定
?这将使您在没有工作的情况下获得正确的扣减:

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);
}
使用名称空间phx::arg\u名称;
无效测试()
{
std::map mymap;
使用Pair=std::Pair;
std::find_if(mymap.begin(),mymap.end(),phx::bind(&Pair::first,arg1)==1);
}
当然,如果需要,可以检测配对类型

完整代码

#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();
}
#包括
#包括
#包括
名称空间phx=boost::phoenix;
结构对\u优先\u执行
{
模板结构结果{typedef typename TPair::first_type const&type;};
模板
typename TPair::first_type const&operator()(TPair const&pair)const{
返回对。第一;
}
模板
typename TPair::first_type&operator()(TPair&pair){
返回对。第一;
}
};
静态phx::首先是函数对;
void test1()
{
使用phx::占位符::\u 1;
std::map mymap;
std::find_if(mymap.begin(),mymap.end(),pair_first(_1)==1);
}
void test2()
{
使用Pair=std::Pair;
使用名称空间phx::arg_名称;
std::map mymap;
std::find_if(mymap.begin(),mymap.end(),phx::bind(&Pair::first,arg1)==1);
}
void test3()
{
std::map mymap;
使用Pair=decltype(mymap)::值\类型;
使用名称空间phx::arg_名称;
std::find_if(mymap.begin(),mymap.end(),phx::bind(&Pair::first,arg1)==1);
}
int main()
{
test1();
test2();
test3();
}

您使用了错误的占位符
\u 1
。你需要一个真正的凤凰演员:

std::find_if(mymap.begin(), mymap.end(), pair_first(phx::placeholders::_1) == 1);
OTOH,你的函子有不一致的
结果类型
协议。当您使用
BOOST\u SPIRIT\u RESULT\u OF\u use\u DECLTYPE
时,这可能不会影响您。为什么不直接使用
绑定
?这将使您在没有工作的情况下获得正确的扣减:

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);
}
使用名称空间phx::arg\u名称;
无效测试()
{
std::map mymap;
使用Pair=std::Pair;
std::find_if(mymap.begin(),mymap.end(),phx::bind(&Pair::first,arg1)==1);
}
当然,如果需要,可以检测配对类型

完整代码

#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();
}
#包括
#包括
#包括
名称空间phx=boost::phoenix;
结构对\u优先\u执行
{
模板结构结果{typedef typename TPair::first_type const&type;};
模板
typename TPair::first_type const&operator()(TPair const&pair)const{
返回对。第一;
}
模板
typename TPair::first_type&operator()(TPair&pair){
返回对。第一;
}
};
静态phx::首先是函数对;
void test1()
{
使用phx::占位符::\u 1;
std::map mymap;
std::find_if(mymap.begin(),mymap.end(),pair_first(_1)==1);
}
void test2()
{
使用Pair=std::Pair;
使用名称空间phx::arg_名称;
std::map mymap;
std::find_if(mymap.begin(),mymap.end(),phx::bind(&Pair::first,arg1)==1);
}
void test3()
{
std::map mymap;
使用Pair=decltype(mymap)::值\类型;
使用名称空间phx::arg_名称;
std::find_if(mymap.begin(),mymap.end(),phx::bind(&Pair::first,arg1)==1);
}
int main()
{
test1();
test2();
test3();
}

我通过查看找到了解决方案(与phoenix不同;我希望phoenix文档能够解释):


我通过回顾找到了解决方案(与phoenix不同;我希望phoenix docs能够解释):


我知道这不是最终的目标,但是你能为
std::pair
专门化
pair\u first\u impl::operator()
?如果这样做有效,那可能意味着
模板操作符()
太贪婪了,它把所有东西都当作参数,甚至是其他懒惰的函数(比如
\u 1
本身)。此外,我认为有一个
凤凰城:at\u c
可以做到这一点,我现在找不到它。我知道at_c,但不是很自我记录,所以我宁愿创建一个懒惰的函数。我认为它只是用来
boost::phoenix::at_c(_1)
,它是在
boost/phoenix/fusion/at.hpp
中定义的,但是你可能需要先制作一个适应的融合序列。我将把这作为一个答案,以使代码更加清晰。我知道这不是最终目标,但您能否首先专门化
pair\u\u impl::operator()
以获得
std::pair
?如果这样做有效,那可能意味着
模板操作符()
太贪婪了,它把所有东西都当作参数,甚至是其他懒惰的函数(比如
\u 1
本身)。此外,我认为有一个
凤凰城:at\u c
可以做到这一点,我现在找不到它。我知道at_c,但不是很自我记录,所以我宁愿创建一个懒惰的函数。我认为它只是用来
boost::phoenix::at_c(_1)
,它是在
boost/phoenix/fusion/at.hpp
中定义的,但是你可能需要先制作一个适应的融合序列。我将把这作为一个答案,使代码更加清晰。
#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();
}
struct pair_first_impl
{
   template<class> struct result;

   template<class F, class TPair>
   struct result<F(TPair)>
   {
      typedef typename boost::remove_reference<TPair>::type actual_type;
      typedef typename actual_type::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);
   return 0;
}
using namespace boost::phoenix::placeholders;
namespace phx = boost::phoenix;