我最近对lambda可以分配给std::function
s这一事实感到惊讶。略有不同的意思是当函数
指定返回val
时,lambda的返回值可能会被忽略,或者参数可能是函数
中的引用,但lambda中的值。
请参阅此示例(ideone),其中我突出显示了我怀疑不兼容的内容。我认为返回值不是问题,因为您总是可以调用函数并忽略返回值,但从引用到值的转换对我来说看起来很奇怪:
int main() {
function<void(const int& i)> f;
// ^^^^ ^^^^^ ^
f = [](int i) -> int { cout<<i<<endl; return i; };
// ^^^ ^^^^^^
f(2);
return 0;
}
小问题是:为什么这段代码要编译并运行?主要问题是:当与std::function
一起使用时,lambda参数和返回值的类型转换的一般规则是什么?
匿名用户
赋值运算符定义为具有以下效果:
function(std::forward<F>(f)).swap(*this);
(14882:2011 20.8.11.2.1第18段)
此引用的构造函数,
template <class F> function(F f);
要求:
F
应为可复制的
<对于参数类型ArgTypes
和返回类型R
,code>f应可调用
(20.8.11.2)。
其中,可调用的
定义如下:
类型为f
的可调用对象f
对于参数类型ArgTypes
和返回类型R
,如果表达式INVOKE(f,declval
INVOKE
反过来定义为:
>
定义调用(f,t1,t2,…,tN)如下:
。。。这里省略了处理成员函数的案例
f(t1,t2,…,tN)
在所有其他情况下
将调用(f,t1,t2,…,tN,R)定义为静态
由于INVOKE
定义变成了一个普通的函数调用,在这种情况下,可以转换参数:如果std::function
int main() {
std::function<void(const int& i)> f;
f = [](int i) -> void { std::cout << i << std::endl; };
f(2);
return 0;
}
返回类型(void
)由static\u cast处理
但是,请注意,在编写本文时,以下内容在使用clang-std=c 1z-stdlib=libc-W转换-Wall
编译时会产生错误,但在使用clang-std=c 1z-stdlib=libstdc-W转换-Wall
编译时不会产生错误:
int main() {
std::function<void(const int& i)> f;
f = [](int i) -> int { std::cout << i << std::endl; return i;};
f(2);
return 0;
}
这是由于libc
实现了C 14中指定的行为,而不是上面描述的修改后的行为(感谢@Jonathan Wakely指出这一点)。@ArunMu在他的帖子中描述了负责同样的事情的libstdc
类型特征。在这方面,在处理具有val
返回类型的可调用对象时,实现的行为可能会略有不同,具体取决于它们是实现C 11、14还是更新的东西。
从引用到值的转换在我看来很奇怪
为什么?
这看起来也很奇怪吗?
int foo(int i) { return i; }
void bar(const int& ir) { foo(ir); }
这完全一样。按值取int
的函数被另一个按常量引用取int
的函数调用。
在bar
内部,变量ir
被复制,返回值被忽略。这正是std::f
可以将lambda分配给std::function类型的函数对象
也就是说,如果你给你的lambda一个id,这样我们就可以参考它的类型,
auto l = [](int i) -> int { cout<<i<<endl; return i; };
将其分配给
函数
static_cast<void>(std::declval<decltype(l)&>()(std::declval<const int&>()))
必须格式良好。
std::declval的结果
return l(static_cast<int const&>(int{}));
正如您所观察到的,如果函数对象签名具有返回类型
val
,则返回值将被丢弃;否则,返回类型必须是隐式可转换的。正如Jonathan Wakely指出的,C 11在这方面的行为不令人满意(使用'std::f
本文向大家介绍js不同数据类型的值的比较,是怎么转换的,有什么规则?相关面试题,主要包含被问及js不同数据类型的值的比较,是怎么转换的,有什么规则?时的应答技巧和注意事项,需要的朋友参考一下 参考回答:
2. 指针类型的参数和返回值 首先看以下程序: 例 23.1. 指针参数和返回值 #include <stdio.h> int *swap(int *px, int *py) { int temp; temp = *px; *px = *py; *py = temp; return px; } int main(void) { int i = 10, j = 20; int *p
我试图创建一个Java方法,它接受一个对象类型和它应该转换成的数据类型。 例如,如果我应该能够返回一个值1作为Int或双根据需要。我使用类传递数据类型作为参数。 问题:如何使方法泛型以接受基于输入参数的返回类型? 下面的代码只是一个示例,它可能在语法上不正确,用于解释我的问题。
问题内容: 有了这个代码 我得到以下异常 我的猜测是,由于缺少Jackson,该对象无法转换为JSON。我不明白为什么,因为我以为杰克逊内置弹簧靴。 然后我试图将Jackson添加到pom.xml中,但是我仍然遇到相同的错误 我是否需要更改任何Spring Boot属性才能使其正常工作? 谢谢 问题答案: 问题是Foo中的一个嵌套对象没有任何对象
我读过这篇文章:java中arrays.aslist(array)与新arraylist (arrays.aslist(ia))之间的差异 当然,包装器上不允许一些列表操作,比如从列表中添加或删除元素,您只能读取或覆盖元素。 如果list2有List接口的引用,我期望它用Java实现List接口中包含的所有方法。https://docs.oracle.com/javase/7/docs/api/j
本文向大家介绍写出js各类型转化为Boolean的值分别是什么?及转化的规则是什么?相关面试题,主要包含被问及写出js各类型转化为Boolean的值分别是什么?及转化的规则是什么?时的应答技巧和注意事项,需要的朋友参考一下 类型 值 Number 除和以外为 String 非空为 Boolean 为 Undefined Null Object 除以外为 Function Symbol BigInt