Lambda表达式作为类模板参数 [英] Lambda expressions as class template parameters
问题描述
可以将lambda表达式用作类模板参数吗? (请注意,这是一个与这一个非常不同的问题,它询问是否lambda表达式本身可以模板化。)
Can lambda expressions be used as class template parameters? (Note this is a very different question than this one, which asks if a lambda expression itself can be templated.)
我问你是否可以这样做:
I'm asking if you can do something like:
template <class Functor>
struct Foo { };
// ...
Foo<decltype([]()->void { })> foo;
这在例如类模板有各种参数例如 equal_to
或者什么,通常实现为一线函数。例如,假设我想实例化一个使用我自己的自定义等式比较函数的哈希表。我想能够说一些像:
This would be useful in cases where, for example, a class template has various parameters like equal_to
or something, which are usually implemented as one-liner functors. For example, suppose I want to instantiate a hash table which uses my own custom equality comparison function. I'd like to be able to say something like:
typedef std::unordered_map<
std::string,
std::string,
std::hash<std::string>,
decltype([](const std::string& s1, const std::string& s2)->bool
{ /* Custom implementation of equal_to */ })
> map_type;
但是我在GCC 4.4和4.6上测试了它,它不工作,显然是因为匿名由lambda表达式创建的类型没有默认构造函数。 (我记得一个类似的问题与 boost :: bind
。)有一些原因草案标准不允许这个,或者我错了,它是允许的,但GCC
But I tested this on GCC 4.4 and 4.6, and it doesn't work, apparently because the anonymous type created by a lambda expression doesn't have a default constructor. (I recall a similar issue with boost::bind
.) Is there some reason the draft standard doesn't allow this, or am I wrong and it is allowed but GCC is just behind in their implementation?
推荐答案
我问你是否可以做一些类似的工作: / p>
I'm asking if you can do something like:
Foo<decltype([]()->void { })> foo;
不能,因为lambda表达式不会出现在未评估的上下文中c $ c> decltype 和 sizeof
等)。
C ++ 0x FDIS,5.1.2 [expr.prim.lambda] p2
No you can't, because lambda expressions shall not appear in an unevaluated context (such as decltype
and sizeof
, amongst others).
C++0x FDIS, 5.1.2 [expr.prim.lambda] p2
导致临时的临时值(12.2)。这个临时变量称为
闭包对象。 lambda表达式不应出现在未求值的操作数中(第5条)。 [注意:A
闭包对象的行为类似于一个函数对象(20.8).- end note]
(强调我)
The evaluation of a lambda-expression results in a prvalue temporary (12.2). This temporary is called the closure object. A lambda-expression shall not appear in an unevaluated operand (Clause 5). [ Note: A closure object behaves like a function object (20.8).—end note ] (emphasis mine)
您需要首先创建一个特定的lambda,然后使用decltype:
You would need to first create a specific lambda and then use decltype on that:
auto my_comp = [](const std::string& left, const std::string& right) -> bool {
// whatever
}
typedef std::unordered_map<
std::string,
std::string,
std::hash<std::string>,
decltype(my_comp)
> map_type;
这是因为每个lambda派生的闭包对象可以有一个完全不同的类型, em> anonymous 功能。
That is because each lambda-derived closure object could have a completely different type, they're like anonymous functions after all.
这篇关于Lambda表达式作为类模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!