I'd suggest a trait, indeed like you almost had with first_type
:
namespace detail // by convention, hide details from enclosing namespace
{
template <typename Pair, typename First = typename std::remove_reference<Pair>::type::first_type>
struct first_type {
typedef First type;
};
// Now you can use the trait in your `first_impl` return type:
template <typename Pair>
typename first_type<Pair>::type first_impl(Pair const& p){
return p.first;
}
}
Now, you can indeed use in the adaption:
BOOST_PHOENIX_ADAPT_FUNCTION(typename detail::first_type<A0>::type, first, detail::first_impl, 1)
Fully working demo: See it Live on Coliru
int main()
{
using boost::phoenix::arg_names::arg1;
std::map<std::string, int> const m {
{ "one", 1 },
{ "two", 2 },
{ "three", 3 },
{ "four", 4 }
};
std::for_each(begin(m), end(m), std::cout << first(arg1) << "\n");
}
Output
four
one
three
two