不能使用显式类型化的lambda
Cannot use explicitly typed lambda
我有这个代码:
std::function<std::string&(std::string&)> change_str = [](std::string& str){
return (str = "Hello world!");
};
std::string s;
std::cout << change_str(s) << std::endl;
它不编译,并说:
main.cpp:8:47: error: no viable conversion from '(lambda at main.cpp:8:60)' to 'std::function<std::string &(std::string &)>'
std::function<std::string&(std::string&)> change_str = [](std::string& str){
^ ~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/v1/functional:1448:5: note: candidate constructor not viable: no known conversion from '(lambda at main.cpp:8:60)' to 'nullptr_t' for 1st argument
function(nullptr_t) _NOEXCEPT : __f_(0) {}
^
/usr/include/c++/v1/functional:1449:5: note: candidate constructor not viable: no known conversion from '(lambda at main.cpp:8:60)' to 'const std::__1::function<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > &(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > &)> &' for 1st argument
function(const function&);
^
/usr/include/c++/v1/functional:1450:5: note: candidate constructor not viable: no known conversion from '(lambda at main.cpp:8:60)' to 'std::__1::function<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > &(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > &)> &&' for 1st argument
function(function&&) _NOEXCEPT;
^
/usr/include/c++/v1/functional:1454:41: note: candidate template ignored: disabled by 'enable_if' [with _Fp = (lambda at main.cpp:8:60)]
__callable<_Fp>::value &&
^
main.cpp:8:60: note: candidate function
std::function<std::string&(std::string&)> change_str = [](std::string& str){
^
1 error generated.
然而,如果我将std::function
的声明更改为auto
,那么它就起作用了:
auto change_str = ...
为什么显式类型不适用于lambda?
一个没有返回类型的lambda是auto
,并自动删除外部引用,因此您不会返回string&
,而只返回string
。
只需将功能声明为
std::function<std::string&(std::string&)> change_str =
[](std::string& str) -> string& ///<--- NOTE THIS
{
return (str = "Hello world!");
};
lambda的推导返回类型是std::string
,这就是为什么您的声明不匹配的原因。但是当您明确指定返回类型时,它是有效的:
std::function<std::string&(std::string&)> change_str =
[](std::string& str) -> std::string&
{
return (str = "Hello world!");
};
正如其他人所说,问题是默认返回类型推导出的std::string
与预期的std::string&
不兼容。
解决这一问题的各种声明目录:
// be completely explicit about the return type
[](std::string& str) -> std::string& {
// be explicit about returning lvalue reference
[](std::string& str) -> auto& {
// be explicit that you're returning some kind of reference type,
// but use reference collapsing to determine if it's an lvalue or rvalue reference
[](std::string& str) -> auto&& {
// use C++14 feature to deduce reference type
[](std::string& str) -> decltype(auto) {
这些是按最少到最多通用的顺序列出的。然而,在这种情况下,没有特别需要泛型:您只是在推导返回类型,因为这是默认的/最少的类型。在这些中,我可能会说明确可能是最好的:[](std::string &str) -> std::string& {
quantdev删除了他的答案,我认为这是另一个很好的建议:
[](std::string& str) {
return std::ref(str = "Hello world!");
};
这是因为std::function
只需要与参数和返回类型进行适当的可转换性,并且在这里返回std::ref
的结果满足了这一要求。
使用std::ref
和使用显式std::string &
返回类型对我来说似乎都是可读的。通过对我的实现进行优化,两者产生的效果完全相同,所以如果你喜欢std::ref
的外观,那么没有什么理由不使用它。
没有返回类型的lambda表现为auto
,它遵循模板参数推导规则,并且您的返回类型被推断为std::string
而不是std::string&
如果类型被明确指定,一切都很好
std::function<std::string&(std::string&)> change_str =
[](std::string& str) -> std::string& {
return (str = "Hello world!");
};
相关文章:
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 可组合的lambda/std::函数与std::可选
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 如何将lambda作为模板类的成员函数参数
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 在 lambda 捕获中声明的变量的类型推导
- 我可以将调用类的"this"传递给 lambda 函数吗?
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- 模板函数指针和lambda
- 两组使用lambda函数的大括号
- 使lambda不可复制/不可移动
- FLTK:按下哪个按钮 - 将数字传递给按钮的回调 (lambda)
- 尝试将lambda函数放在队列中时出现一般分配器错误(可能是与unique_ptr有关的错误)
- 将带有unique_ptr的可变 lambda 传递给 const&std::function
- AWS Lambda C++运行时权限被拒绝
- 捕获lambda中的std::数组
- 这 4 个 lambda 表达式之间有什么区别?
- 将自动类型化 lambda 与模板化函数一起使用 - 在 g++ 5.4 中使用自动模板推导
- 不能使用显式类型化的lambda