C++11 lambda 可以分配给签名不正确的 std::function
C++11 lambda can be assigned to std::function with incorrect signature
编译运行如下(Apple LLVM version 6.1.0 and Visual C++ 2015):
#include <functional>
#include <iostream>
struct s { int x; };
int main(int argc, char **argv)
{
std::function<void (s &&)> f = [](const s &p) { std::cout << p.x; };
f(s {1});
return 0;
}
为什么赋值 std::function<void (s &&)> f = [](const s &p) { std::cout << p.x; };
没有产生错误?接受右值引用的函数不应该与接受 const 左值引用的函数具有相同的签名,不是吗?从 lambda 的声明中删除 const
确实会按预期产生错误。
请对此持保留态度。这是我的理解,但我不确定。
考虑以下输出:
int main(int argc, char **argv)
{
std::cout << std::is_convertible<s &&, s&>::value << std::endl; //false
std::cout << std::is_convertible<s &&, const s&>::value << std::endl; //true
std::cout << std::is_convertible<const s &, s&&>::value << std::endl; //false
return 0;
}
这表明可以将 s &&
转换为 const s&
。这就是 std::function
的赋值没问题的原因。
Dropping the const from the lambda's declaration does generate an
error as expected.
的确,这是因为(如前所示),无法将 s &&
转换为 s &
。
同理,反其道而行之:
std::function<void (const s &)> f = [](s &&p) { std::cout << p.x; };
会失败,因为无法转换 const s&
s &&
.
扩展现有评论和答案:
std::function<R(A...)>
的要点是它可以包装任何可以用 A...
调用的函数或函子,并将结果存储在 R
.
中
因此,例如,
std::function<int(int)> f = [](long l) { return l; };
只是桃色。
所以当你看到这样的事情时,你必须问自己:如果你有一个采用 const T &
的 lambda,并且你有一个 T &&
类型的表达式(或者,更准确地说,你有一个类型为 T
) 的 xvalue,您可以使用该表达式调用 lambda 吗?
是的,你可以。
如果可以,那么 std::function
应该能够存储该函子。这几乎是 std::function
.
的要点
编译运行如下(Apple LLVM version 6.1.0 and Visual C++ 2015):
#include <functional>
#include <iostream>
struct s { int x; };
int main(int argc, char **argv)
{
std::function<void (s &&)> f = [](const s &p) { std::cout << p.x; };
f(s {1});
return 0;
}
为什么赋值 std::function<void (s &&)> f = [](const s &p) { std::cout << p.x; };
没有产生错误?接受右值引用的函数不应该与接受 const 左值引用的函数具有相同的签名,不是吗?从 lambda 的声明中删除 const
确实会按预期产生错误。
请对此持保留态度。这是我的理解,但我不确定。
考虑以下输出:
int main(int argc, char **argv)
{
std::cout << std::is_convertible<s &&, s&>::value << std::endl; //false
std::cout << std::is_convertible<s &&, const s&>::value << std::endl; //true
std::cout << std::is_convertible<const s &, s&&>::value << std::endl; //false
return 0;
}
这表明可以将 s &&
转换为 const s&
。这就是 std::function
的赋值没问题的原因。
Dropping the const from the lambda's declaration does generate an error as expected.
的确,这是因为(如前所示),无法将 s &&
转换为 s &
。
同理,反其道而行之:
std::function<void (const s &)> f = [](s &&p) { std::cout << p.x; };
会失败,因为无法转换 const s&
s &&
.
扩展现有评论和答案:
std::function<R(A...)>
的要点是它可以包装任何可以用 A...
调用的函数或函子,并将结果存储在 R
.
因此,例如,
std::function<int(int)> f = [](long l) { return l; };
只是桃色。
所以当你看到这样的事情时,你必须问自己:如果你有一个采用 const T &
的 lambda,并且你有一个 T &&
类型的表达式(或者,更准确地说,你有一个类型为 T
) 的 xvalue,您可以使用该表达式调用 lambda 吗?
是的,你可以。
如果可以,那么 std::function
应该能够存储该函子。这几乎是 std::function
.