首先,我使用的是 C++11(我的话题很烂)。
我正在尝试做的是编写一个通用模板函数来实现通常sort_by
在其他编程语言中调用的东西。它涉及为范围的每个成员只计算一次任意标准,然后根据这些标准对该范围进行排序。这样的标准不一定是 POD,它必须是不可比的。对于std::less
不起作用的事情,调用者应该能够提供她自己的比较函子。
我已经成功编写了使用以下签名的函数:
template< typename Tcriterion
, typename Titer
, typename Tcompare = std::less<Tcriterion>
>
void
sort_by(Titer first, Titer last,
std::function<Tcriterion(typename std::iterator_traits<Titer>::value_type const &)> criterion_maker,
Tcompare comparator = Tcompare()) {
}
它可以像这样使用:
struct S { int a; std::string b; double c; };
std::vector<S> s_vec{
{ 42, "hello", 0.5 },
{ 42, "moo!", 1.2 },
{ 23, "fubar", 0.2 },
};
sort_by1< std::pair<int, double> >(
s_vec.begin(), s_vec.end(),
[](S const &one_s) { return std::make_pair(one_s.a, one_s.c); }
);
我不喜欢这种方法的是我必须自己提供Tcriterion
参数,因为编译器无法从 lambda 表达式中推断出该类型。因此这不起作用:
sort_by1(s_vec.begin(), s_vec.end(), [](S const &one_s) { return std::make_pair(one_s.a, one_s.c); });
clang 3.1 和 gcc 4.7.1 都对此大喊大叫(gcc 4.7.1 甚至对上面的代码大喊大叫,所以我想我真的在这里做错了)。
但是,如果我将 lambda 分配给std::function
第一个,那么至少 clang 3.1 可以推断出参数,这意味着它有效:
typedef std::pair<int, double> criterion_type;
std::function<criterion_type(S const &)> criterion_maker = [](S const &one_s) {
return std::make_pair(one_s.a, one_s.c);
};
sort_by1(s_vec.begin(), s_vec.end(), criterion_maker);
所以我的问题是:我如何更改我的函数签名,以便我不需要指定那个参数?并且(可能相关)我将如何修复我的示例以使其与 gcc 一起使用?