我需要一个懒惰的评估版std :: pair.first。我的方法是使用boost :: phoenix,定义模板化函数并使用BOOST_PHOENIX_ADAPT_FUNCTION makro作为下列文件:
template <typename T1, typename T2>
T1 first_impl(std::pair<T1,T2> p){
return p.first;
}
BOOST_PHOENIX_ADAPT_FUNCTION(std::string, first, first_impl, 1);
对于我当前程序中需要的特定情况很好(在我的情况下为T1 = std :: string)。但是,如何使用first_impl函数模板的结果类型T1进一步抽象以供将来使用? The documentation提到使用typename remove_reference<A0>::type
作为makro的第一个参数来定义函数的返回类型作为其第一个参数的类型。基于此,我尝试了几个版本:
BOOST_PHOENIX_ADAPT_FUNCTION(typename A0::first_type, first, first_impl, 1);
尝试访问std::pair<T1, T2>::first_type
,这对我来说似乎不起作用。
另外,我尝试调整std::remove_reference
处理的内容,如下所示
template <typename T1, typename T2> first_type < std::pair<T1,T2> >
{ typedef T1 type; }
但这似乎也不起作用。 有人能指出我在这里做错了吗?
答案 0 :(得分:3)
我建议一个特点,就像你几乎和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;
}
}
现在,您确实可以在适应中使用:
BOOST_PHOENIX_ADAPT_FUNCTION(typename detail::first_type<A0>::type, first, detail::first_impl, 1)
完全正常工作的演示:请参阅 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");
}
输出
four
one
three
two