I found the solution by reviewing the result_of protocol documentation (which is separate from phoenix; I was expecting phoenix docs to explain):
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;
}
The problem was that I thought that the type passed into the template parameter for the nested result
struct was the type of the first parameter, which it isn't. It's actually the whole function type. So a template specialization of result
must be created the can be used to extract the type of the first argument. You can then use this to access first_type
in the pair.
My _1
placeholder is valid because at the top of my source file I'm doing the following:
using namespace boost::phoenix::placeholders;
namespace phx = boost::phoenix;