将 decltype 和 std::function 与 lambda 一起使用

Posted

技术标签:

【中文标题】将 decltype 和 std::function 与 lambda 一起使用【英文标题】:Use decltype and std::function with lambda 【发布时间】:2012-11-17 21:17:27 【问题描述】:

这行得通...

auto x = 4;
typedef decltype(x) x_t;
x_t y = 5;

...那为什么不呢?

int j = 4;  
auto func = [&] (int i)  cout << "Hello: i=" << i << "  j=" << j << endl;;
typedef decltype(func) lambda_t;
lambda_t func2 = [&] (int i)  cout << "Bye: i=" << i << "  j=" << j << endl;;

... 我将如何使用 std::function 手动声明 lambda_t

【问题讨论】:

【参考方案1】:

...那么为什么这 [工作] 不起作用?

因为 lambda 的每个词法实例都有不同的类型。是否使用相同的字符无关紧要。

.. 我将如何使用 std::function 手动声明 lambda_t?

lambda 接受一个 int 参数并且不返回任何内容...因此:

typedef std::function<void(int)> lambda_t;

【讨论】:

【参考方案2】:

Lambda 类型是 unutterable(无法命名),这就是您无法按照您的要求做的原因。除此之外,每个 lambda 都是不同的类型,因此即使您可以命名类型,也无法将第二个 lambda 分配给第一个。如果您将 lambda 语法视为函数对象的快捷方式,就会变得更加清晰:成员 operator() 对于每个 lambda 都是不同的,因此它们属于不同的类型。

另一方面,您可以将 lambda 分配给具有适当签名的 std::function&lt;&gt; 对象,在您的情况下为 std::function&lt;void(int)&gt;

【讨论】:

你当然可以用这样的 decltype 来 typedef lambdas。 @R.MartinhoFernandes 提出了一个问题,为什么 decltype(func) 不返回 std::function&lt;void(int)&gt; 而不是一些无法使用的垃圾? @learnvst:为什么要这样? decltype 返回声明的类型,而 lambda 不是 std::function。此外,由于类型擦除,std::function 对性能有影响。 @learnvst:这不是无法使用的垃圾。但我在***.com/questions/11628765/…之前已经回答了你的问题【参考方案3】:

这里有一些确凿的证据表明这是行不通的。类似场景:

int foo = 3;
int bar = 3;

std::cout << (typeid(foo).hash_code() == typeid(bar).hash_code()); // prints one -- obviously - they are the same type

现在,让我们使用完全相同的代码,但使用 lambda。你认为会有什么反应。

  auto foo = []()std::cout << "HELLO\n"; ;

  auto bar = []()std::cout << "HELLO\n"; ;

  std::cout << (typeid(foo).hash_code() == typeid(bar).hash_code()); // prints 0 -- different type even though they are declared exactly the same.

【讨论】:

以上是关于将 decltype 和 std::function 与 lambda 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

C++11新特性:3—— 汇总auto和decltype的区别

decltype类型指示符

decltype 和括号

c++ 中decltype怎么用?

complexType

decltype总结