web-dev-qa-db-ja.com

ラムダ式をテンプレートパラメーターとして使用するにはどうすればよいですか?

ラムダ式をテンプレートパラメーターとして使用するにはどうすればよいですか?例えば。 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;
32
user283145

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);
33
kennytm

このように使用されるコンパレータの場合は、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);
  }
};
4
Roger Pate

これがあなたが求めているものであるかどうかはわかりませんが、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)>;
1
Ken Simon

問題は、最後のテンプレートパラメータがオブジェクトではなくタイプであるため、次のことを行うことをお勧めします

    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);

乾杯

0