请考虑以下示例:
#include <cstdlib>
int main() {
const int m = 42;
[] { m; }(); // OK
const int n = std::rand();
[] { n; }(); // error: 'n' is not captured
}
Run Code Online (Sandbox Code Playgroud)
为什么我需要捕获n第二个lambda而不是m第一个lambda?我在C++ 14标准中检查了第5.1.2节(Lambda表达式)但我无法找到原因.你能指点我解释一个段落吗?
更新:我在GCC 6.3.1和7(主干)中观察到了这种行为.Clang 4.0和5(主干)在两种情况下都失败并出错(variable 'm' cannot be implicitly captured in a lambda with no capture-default specified).
定义int->int通过引用接收lambda参数的函数的正确方法是什么?
void f(std::function< int(int) >& lambda);
Run Code Online (Sandbox Code Playgroud)
要么
void f(auto& lambda);
Run Code Online (Sandbox Code Playgroud)
我不确定最后一种形式是否是合法的语法.
还有其他方法来定义lambda参数吗?
我正在使用Java 8中的新lambda特性,并发现Java 8提供的实践非常有用.但是,我想知道是否有一种很好的方法可以解决以下情况.假设您有一个对象池包装器,需要某种工厂来填充对象池,例如(使用java.lang.functions.Factory):
public class JdbcConnectionPool extends ObjectPool<Connection> {
public ConnectionPool(int maxConnections, String url) {
super(new Factory<Connection>() {
@Override
public Connection make() {
try {
return DriverManager.getConnection(url);
} catch ( SQLException ex ) {
throw new RuntimeException(ex);
}
}
}, maxConnections);
}
}
Run Code Online (Sandbox Code Playgroud)
将函数接口转换为lambda表达式后,上面的代码变为:
public class JdbcConnectionPool extends ObjectPool<Connection> {
public ConnectionPool(int maxConnections, String url) {
super(() -> {
try {
return DriverManager.getConnection(url);
} catch ( SQLException ex ) {
throw new RuntimeException(ex);
}
}, maxConnections); …Run Code Online (Sandbox Code Playgroud) 和Lambdas一起玩,我发现了一个我不完全理解的有趣行为.
我有一个struct Overload派生自2个模板参数,并有一个using F1::operator();子句.
现在,如果我从两个函子派生,我只能访问F1的operator()(正如我所料)
如果我从两个Lambda函数派生,则不再适用:我也可以从F2访问operator().
#include <iostream>
// I compiled with g++ (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8)
//
// g++ -Wall -std=c++11 -g main.cc
// g++ -Wall -std=c++11 -DFUNCTOR -g main.cc
//
// or clang clang version 3.3 (tags/RELEASE_33/rc2)
//
// clang++ -Wall -std=c++11 -g main.cc
// clang++ -Wall -std=c++11 -DFUNCTOR -g main.cc
//
// on a Linux localhost.localdomain 3.9.6-200.fc18.i686 #1 SMP Thu Jun 13
// 19:29:40 UTC 2013 i686 i686 i386 GNU/Linux box …Run Code Online (Sandbox Code Playgroud) 以下递归lambda调用如何结束/终止?
#include <cstdio>
auto terminal = [](auto term) // <---------+
{ // |
return [=] (auto func) // | ???
{ // |
return terminal(func(term)); // >---------+
};
};
auto main() -> int
{
auto hello =[](auto s){ fprintf(s,"Hello\n"); return s; };
auto world =[](auto s){ fprintf(s,"World\n"); return s; };
terminal(stdout)
(hello)
(world) ;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在这里错过了什么?
我看到代表有两种形式:
A. Func<string, string> convertMethod = lambda
B. public delegate string convertMethod(string value);
Run Code Online (Sandbox Code Playgroud)
我不确定这两者之间究竟有什么区别.他们都是代表吗?我相信第一个会使用lambda,第二个必须有一个方法来实际执行工作.我也可能感到困惑.
请看下面的代码:
Method methodInfo = MyClass.class.getMethod("myMethod");
Run Code Online (Sandbox Code Playgroud)
这可行,但方法名称作为字符串传递,因此即使myMethod不存在,这也将编译.
另一方面,Java 8引入了方法引用功能.它在编译时检查.可以使用此功能获取方法信息吗?
printMethodName(MyClass::myMethod);
Run Code Online (Sandbox Code Playgroud)
完整示例:
@FunctionalInterface
private interface Action {
void invoke();
}
private static class MyClass {
public static void myMethod() {
}
}
private static void printMethodName(Action action) {
}
public static void main(String[] args) throws NoSuchMethodException {
// This works, but method name is passed as a string, so this will compile
// even if myMethod does not exist
Method methodInfo = MyClass.class.getMethod("myMethod");
// Here we pass reference to a method. It …Run Code Online (Sandbox Code Playgroud) 在lambda中,局部变量需要是final,但实例变量不需要.为什么这样?
在尝试Visual Studio 2015 RC时,我收到了以前正在运行的代码的运行时错误.给定(x => x.CustomerStatusID == CustomerStatuses.Active)作为a传递给函数的lambda Expression<>,调试器在表达式树中显示差异.以前编译为:
.Lambda #Lambda1<System.Func`2[Services.DataClasses.CustomerDC,System.Boolean]>(Services.DataClasses.CustomerDC $x)
{
(System.Int32)$x.CustomerStatusID == 0
}
Run Code Online (Sandbox Code Playgroud)
但是在C#6.0中它现在编译为
.Lambda #Lambda1<System.Func`2[Services.DataClasses.CustomerDC,System.Boolean]>(Services.DataClasses.CustomerDC $x)
{
(System.Int32)$x.CustomerStatusID == (System.Int32).Constant<Services.DataClasses.CustomerStatuses>(Active)
}
Run Code Online (Sandbox Code Playgroud)
虽然我的树遍历代码的修复是直截了当的,并且额外的细节是值得赞赏的,有没有人知道任何其他陷阱漂浮这样?
或者,是否有人链接到有关如何改进重载决策的细节的信息?我找不到任何东西.
可以在头文件中写入以下内容:
inline void f () { std::function<void ()> func = [] {}; }
Run Code Online (Sandbox Code Playgroud)
要么
class C { std::function<void ()> func = [] {}; C () {} };
Run Code Online (Sandbox Code Playgroud)
我想在每个源文件中,lambda的类型可能不同,因此包含的类型std::function(target_type的结果会有所不同).
这是一个ODR(一个定义规则)违规,尽管看起来像一个共同的模式和合理的事情?第二个示例是每次都违反ODR还是仅在头文件中至少有一个构造函数?