首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用lambda表达式作为模板参数?

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

Stack Overflow用户
提问于 2010-09-28 07:24:36
回答 4查看 20.2K关注 0票数 33

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

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

代码示例:

代码语言:javascript
复制
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编译标志):

代码语言:javascript
复制
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表达式,因为它们返回了它们所引用的匿名结构的实例。

但是,修复该错误并不能解决问题。我得到以下代码的lambda-expression in unevaluated context错误:

代码语言:javascript
复制
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;
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-09-28 07:39:47

std::set的第二个模板参数期望一个类型,而不是一个表达式,所以您只是错误地使用了它。

您可以创建这样的设置:

代码语言:javascript
复制
auto comp = [](const A& lhs, const A& rhs) -> bool { return lhs.x < rhs.x; };
auto SetOfA = std::set <A, decltype(comp)> (comp);
票数 33
EN

Stack Overflow用户

发布于 2010-09-30 00:19:50

对于采用这种方法的比较器来说,使用非0x方法仍然更好:

代码语言:javascript
复制
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)视为等效的。如果不希望这样做,则需要包含有助于唯一性的其他值:

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2010-09-29 13:29:58

不确定这是否是您想要的,但是返回RetType并接受InType的lambda的签名将是:

代码语言:javascript
复制
std::function<RetType(InType)>

(确保#include <functional>)

您可以通过使用ty胡枝子来缩短这个值,但我不确定您是否可以使用decltype来避免计算实际的类型(因为lambdas显然不能在这个上下文中使用)。

因此,您的类型应该是:

代码语言:javascript
复制
typedef std::function<bool(const A &lhs, const A &rhs)> Comp

代码语言:javascript
复制
using Comp = std::function<bool(const A &lhs, const A &rhs)>;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3810519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档