c++ - 为什么 std::foreach 不能与 std::vector 一起使用?
问题描述
我有以下代码片段,它采用std::vector<int> list
并在所有向量元素中写入零。这个例子工作得很好。
#include <vector>
#include <iostream>
#include <algorithm>
int main () {
std::vector<int> list {1, 1, 2};
auto reset = [](int & element){element = 0;};
auto print = [](int element) {std::cout << element << " ";};
std::for_each(list.begin(), list.end(), reset);
std::for_each(list.begin(), list.end(), print);
}
如果我将向量的类型从 更改int
为bool
,则代码将无法编译。
#include <vector>
#include <iostream>
#include <algorithm>
int main () {
std::vector<bool> list {true, true, false};
auto reset = [](bool & element){element = false;};
auto print = [](int element) {std::cout << element << " ";};
std::for_each(list.begin(), list.end(), reset);
std::for_each(list.begin(), list.end(), print);
}
我不明白编译器错误消息:
/opt/compiler-explorer/gcc-7.2.0/lib/gcc/x86_64-linux-gnu/7.2.0/../../../../include/c++/7.2.0/bits/stl_algo .h:3884:2:错误:没有匹配函数调用类型为“(lambda at :7:18)”的对象
__f(*__first); ^~~
:10:10: 注意:在此处请求的函数模板特化 'std::for_each:7:18)>' 的实例化
std::for_each(list.begin(), list.end(),reset); ^
:7:18: 注意:候选函数不可行:第一个参数没有从“std::_Bit_iterator::reference”(又名“std::_Bit_reference”)到“bool &”的已知转换
auto reset = [](bool & element){element = false;}; ^
:7:18: 注意: 'void (*)(bool &)' 类型的转换候选
为什么可以std::foreach
与 a 一起使用std::vector<int>
,但不能与 a 一起使用std::vector<bool>
?
std::vector<bool>
(见这里)的内存优化是答案的一部分吗?
解决方案
原因
问题源于这样一个事实,即取消引用来自的迭代器std::vector<bool>
不会返回bool&
,而是代理对象。因此,它不被视为 stl 容器(感谢@KillzoneKid)。
使固定
auto element
在参数列表中使用。一般来说,如果您不关心类型,请auto&&
在 lambda 参数列表中使用。
#include <vector>
#include <iostream>
#include <algorithm>
int main () {
std::vector<bool> list {true, true, false};
auto reset = [](auto && element){element = false;};
auto print = [](int element) {std::cout<< element << " ";};
std::for_each(list.begin(), list.end(),reset);
std::for_each(list.begin(), list.end(),print);
}
演示。
尝试使用auto&
会再次触发编译错误,因为返回的代理不是左值,而是右值。因此,auto&&
比平时有更多的好处。
推荐阅读
- ruby-on-rails - post 方法在 Ruby on Rails 中如何工作
- c# - 我可以在 Entity Framework 6 中制作全局查询过滤器吗?通过 OnModelCreating?
- python - 通过蓝牙 python 命令发送到另一个 Raspberry Pi
- java - 如何从 Java 中的 /places/v1/autosuggest 获取 JSON 响应?
- jquery - 通过 jQuery AJAX 在 ASP.Net Core 中返回视图 - 在生产中不起作用
- c++ - C ++检查国际象棋游戏中是否有玩家在路上
- reactjs - 如何在反应中导航到新页面?
- java - Java:方法 org.postgresql.jdbc4.Jdbc4Connection.isValid(int) 尚未实现
- prolog - 试图在序言中打印出 preOrder Traversal
- html - 显示外部 SVG