ラムダ式をテンプレートパラメーターとして使用するにはどうすればよいですか?例えば。 std :: setを初期化する比較クラスとして。
ラムダ式は匿名構造体を作成するだけなので、次のソリューションが機能するはずです。これはテンプレートパラメーターとして適切なはずです。ただし、多くのエラーが発生します。
コード例:
struct A {int x; int y;};
std::set <A, [](const A lhs, const A &rhs) ->bool {
return lhs.x < rhs.x;
} > SetOfA;
エラー出力(g ++ 4.5.1コンパイラと--std = c ++ 0xコンパイルフラグを使用しています):
error: ‘lhs’ cannot appear in a constant-expression
error: ‘.’ cannot appear in a constant-expression
error: ‘rhs’ cannot appear in a constant-expression
error: ‘.’ cannot appear in a constant-expression
At global scope:
error: template argument 2 is invalid
それはGCCの予想される動作ですか、それともバグですか?
[〜#〜]編集[〜#〜]
誰かが指摘したように、参照している匿名構造体のインスタンスを返すため、ラムダ式を誤って使用しています。
ただし、そのエラーを修正しても問題は解決しません。 lambda-expression in unevaluated context
次のコードのエラー:
struct A {int x; int y;};
typedef decltype ([](const A lhs, const A &rhs) ->bool {
return lhs.x < rhs.x;
}) Comp;
std::set <A, Comp > SetOfA;
std::set
の2番目のテンプレートパラメータは、式ではなくタイプを予期しているため、誤って使用しているだけです。
次のようなセットを作成できます。
auto comp = [](const A& lhs, const A& rhs) -> bool { return lhs.x < rhs.x; };
auto SetOfA = std::set <A, decltype(comp)> (comp);
このように使用されるコンパレータの場合は、0x以外のアプローチを使用することをお勧めします。
struct A { int x; int y; };
struct cmp_by_x {
bool operator()(A const &a, A const &b) {
return a.x < b.x;
}
};
std::set<A, cmp_by_x> set_of_a;
ただし、0xでは、cmp_by_xをローカル型にする(つまり、関数内で定義する)ことができます。これは、現在のC++では禁止されている便利な方法です。
また、比較ではA(x = 1、y = 1)とA(x = 1、y = 2)を同等として扱います。それが望ましくない場合は、一意性に寄与する他の値を含める必要があります。
struct cmp_by_x {
bool operator()(A const &a, A const &b) {
return a.x < b.x || (a.x == b.x && a.y < b.y);
}
};
これがあなたが求めているものであるかどうかはわかりませんが、RetTypeを返し、InTypeを受け入れるラムダのシグネチャは次のようになります。
std::function<RetType(InType)>
(必ず#include <functional>
)
Typedefを使用することでそれを短縮できますが、実際の型を理解することを避けるためにdecltypeを使用できるかどうかはわかりません(ラムダは明らかにそのコンテキストでは使用できないため)。
したがって、typedefは次のようになります。
typedef std::function<bool(const A &lhs, const A &rhs)> Comp
または
using Comp = std::function<bool(const A &lhs, const A &rhs)>;
問題は、最後のテンプレートパラメータがオブジェクトではなくタイプであるため、次のことを行うことをお勧めします
std::set <A, std::fuction<bool(const A &,const A &)>>
SetOfA([](const A lhs, const A &rhs) ->bool {
return lhs.x < rhs.x;
} > SetOfA;
簡単にするために、次のことができます。
auto func = SetOfA([](const A lhs, const A &rhs) ->bool { return lhs.x < rhs.x;}
set <A,decltype(func)> SetOfA(func);
乾杯