まず、私はC ++ 11を使用しています(そして私のトピックは最悪です)。
私がやろうとしているのはsort_by
、他のプログラミング言語で通常呼び出されるものを実装するジェネリックテンプレート関数を作成することです。これには、範囲の各メンバーの任意の基準を1回だけ計算し、それらの基準に従ってその範囲を並べ替えることが含まれます。このような基準は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
、コンパイラーがラムダ式からその型を推測できないため、自分で引数を指定する必要があることです。したがって、これは機能しません。
sort_by1(s_vec.begin(), s_vec.end(), [](S const &one_s) { return std::make_pair(one_s.a, one_s.c); });
clang3.1とgcc4.7.1は両方ともこれに吠えます(gcc 4.7.1は上記のコードにも吠えるので、私はここで本当に何か間違ったことをしていると思います)。
ただし、ラムダを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);
だから私の質問は次のとおりです:その1つの引数を指定する必要がないように関数のシグネチャを変更するにはどうすればよいですか?そして(おそらく関連している)gccで動作するように例を修正するにはどうすればよいですか?