C++ 如何使用lambda表达式作为模板参数?

C++ 如何使用lambda表达式作为模板参数?,c++,templates,c++11,lambda,C++,Templates,C++11,Lambda,如何使用lambda表达式作为模板参数?例如,作为比较类初始化std::set 以下解决方案应该可以工作,因为lambda表达式只创建一个匿名结构,它应该适合作为模板参数。然而,产生了许多错误 代码示例: struct A {int x; int y;}; std::set <A, [](const A lhs, const A &rhs) ->bool { return lhs.x < rhs.x; } > SetOfA; 这是GCC中的预期行

如何使用lambda表达式作为模板参数?例如,作为比较类初始化std::set

以下解决方案应该可以工作,因为lambda表达式只创建一个匿名结构,它应该适合作为模板参数。然而,产生了许多错误

代码示例:

struct A {int x; int y;};
std::set <A, [](const A lhs, const A &rhs) ->bool {
    return lhs.x < rhs.x;
    } > SetOfA;
这是GCC中的预期行为还是错误

编辑

正如有人指出的,当lambda表达式返回它们所引用的匿名结构的实例时,我使用的lambda表达式是错误的

但是,修复该错误并不能解决问题。对于以下代码,我在未计算的上下文中得到
lambda表达式
错误:

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;
结构A{intx;inty;}; typedef decltype([](常量A左侧、常量A和右侧)->bool{ 返回左侧x<右侧x; })公司; std::set SetOfA;
std::set的第二个模板参数需要一个类型,而不是一个表达式,所以这只是您错误地使用了它

您可以这样创建集合:

auto comp = [](const A& lhs, const A& rhs) -> bool { return lhs.x < rhs.x; };
auto SetOfA = std::set <A, decltype(comp)> (comp);
autocomp=[](常量A和lhs,常量A和rhs)->bool{return lhs.x
不确定这是否是您要问的问题,但返回RetType并接受InType的lambda的签名将是:

std::function<RetType(InType)>
std::函数
(确保包含)

您可以通过使用typedef来缩短它,但我不确定您是否可以使用decltype来避免计算实际的类型(因为lambdas显然不能在该上下文中使用)

因此,您的typedef应该是:

typedef std::function<bool(const A &lhs, const A &rhs)> Comp
typedef std::函数Comp

使用Comp=std::函数;

对于以这种方式使用的比较器,最好使用非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;
结构A{intx;inty;}; 结构cmp_by_x{ 布尔运算符()(常数A、常数b){ 返回a.x <0>但是,在0x中,当当前的C++(

)禁止时,可以使cMPyByxx成为一个局部类型(即在函数内定义它)。 此外,您的比较将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);
  }
};
struct cmp\u by\u x{
布尔运算符()(常数A、常数b){
返回a.x
问题在于最后一个模板参数的类型不是对象,因此您可能需要执行以下操作

    std::set <A, std::fuction<bool(const A &,const A &)>> 
              SetOfA([](const A lhs, const A &rhs) ->bool {
                                                             return lhs.x < rhs.x;
                                                          } > SetOfA;
std::set
SetOfA([](常数A左侧、常数A和右侧)->bool{
返回左侧x<右侧x;
}>刚毛;
要使其更简单,您可以执行以下操作:

auto func = SetOfA([](const A lhs, const A &rhs) ->bool { return lhs.x < rhs.x;}
set <A,decltype(func)> SetOfA(func);
auto func=SetOfA([](常量A lhs,常量A&rhs)->bool{return lhs.x

欢呼@ < /p>我把它标记为C++ 0x。它似乎更合适,应该得到更好的答案。@ JoHHD不应该也被标记为“C++”吗?0x最终将成为新的标准,我不希望将来的人们错过这个问题,因为他们忘记了正确的标签是C++ 0x而不是C++。(或者,在某个时刻,所有的C++ 0x标签都迁移到C++)?lambda表达式确实是一种类型。它只是用定义的操作符()来声明匿名结构的另一种方式。我不使用lambda作为类型说明符:STD::SER。B@buratina:如果是类型,则

[](){}x;
应该是一个有效的声明。lambda表达式只是该匿名结构的一个实例。您需要一个
decltype
来获取该类型。好的,现在它被清除:)但decltype也不知何故没有work@buratinas:尝试在结构a{int x;int y;}之后添加分号< KnNyTm我希望LAMBDA表达式只是类型,所以您所发布的示例憎恶——<代码> []({ } x;)将是合法C++。为什么Perl有所有的乐趣?在(稍微)更严肃的注释上,这意味着<代码> DECKTYPE([]({ }))x
有效吗?+1因为这是解决方案,但是
std::function
只是一个holder类型。您可以将lambda转换为
function
,并获得指向lambda的对象,但这不是它的原始类型。编辑:该函数不指向lambda,它包含lambda。但它也不是原始类型。啊,好我认为内联lambda语法会生成一些随机生成的类型,这样就不会有两个完全相同的类型了?(C#就是这样做的,IIRC。)+1是获取泛型lambda函数类型的有用方法(无需先将lambda函数放入变量中)。
    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);