如何使用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;
错误输出(我使用 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 表达式,因为它们返回了它们所引用的匿名结构的实例。
但是,修复该错误并不能解决问题。对于以下代码,我收到 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;
How to use lambda expression as a template parameter? E.g. as a comparison class initializing a std::set.
The following solution should work, as lambda expression merely creates an anonymous struct, which should be appropriate as a template parameter. However, a lot of errors are spawned.
Code example:
struct A {int x; int y;};
std::set <A, [](const A lhs, const A &rhs) ->bool {
return lhs.x < rhs.x;
} > SetOfA;
Error output (I am using g++ 4.5.1 compiler and --std=c++0x compilation flag):
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
Is that the expected behavior or a bug in GCC?
EDIT
As someone pointed out, I'm using lambda expressions incorrectly as they return an instance of the anonymous struct they are referring to.
However, fixing that error does not solve the problem. I get lambda-expression in unevaluated context
error for the following code:
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;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
std::set
的第二个模板参数需要一个类型,而不是表达式,所以这只是你错误地使用了它。您可以像这样创建该集合:
The 2nd template parameter of
std::set
expects a type, not an expression, so it is just you are using it wrongly.You could create the set like this:
对于以这种方式使用的比较器,您仍然最好使用非 0x 方法:
但是,在 0x 中,您可以将 cmp_by_x 设为本地类型(即在函数内定义它),这样更方便,但当前的 C++ 禁止这样做。
此外,您的比较将 A(x=1, y=1) 和 A(x=1, y=2) 视为等效。如果不需要,您需要包含有助于唯一性的其他值:
For comparators used this way, you're still better off with a non-0x approach:
However, in 0x you can make cmp_by_x a local type (i.e. define it inside a function) when that is more convenient, which is forbidden by current C++.
Also, your comparison treats A(x=1, y=1) and A(x=1, y=2) as equivalent. If that's not desired, you need to include the other values that contribute to uniqueness:
不确定这是否是您所要求的,但返回 RetType 并接受 InType 的 lambda 签名将是:(
确保
#include
)您可以通过使用来缩短它typedef,但我不确定您是否可以使用 decltype 来避免弄清楚实际类型(因为 lambda 显然不能在该上下文中使用。)
所以您的 typedef 应该是:
或
Not sure if this is what you're asking, but the signature of a lambda which returns RetType and accepts InType will be:
(Make sure to
#include <functional>
)You can shorten that by using a typedef, but I'm not sure you can use decltype to avoid figuring out the actual type (since lambdas apparently can't be used in that context.)
So your typedef should be:
or
问题是最后一个模板参数是类型而不是对象,因此您可能需要执行以下操作
以使其更简单,您可以执行以下操作:
干杯
the problem is the last template parameter is type not an object, so you might want to do the following
to make it simpler you can do the following:
cheers