sch*_*312 10 c++ foreach boolean 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);
}
Run Code Online (Sandbox Code Playgroud)
如果我把改变来自载体的种类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);
}
Run Code Online (Sandbox Code Playgroud)
我不明白编译器错误信息:
/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)'对象
Run Code Online (Sandbox Code Playgroud)__f(*__first); ^~~
:10:10:注意:在实例化函数模板专业化'std :: for_each:7:18)>'请求这里
Run Code Online (Sandbox Code Playgroud)std::for_each(list.begin(), list.end(),reset); ^
:7:18:注意:候选函数不可行:第一个参数没有已知的'std :: _ Bit_iterator :: reference'(又名'std :: _ Bit_reference')转换为'bool&'
Run Code Online (Sandbox Code Playgroud)auto reset = [](bool & element){element = false;}; ^
:7:18:注意:'void(*)(bool&)'类型的转换候选人
为什么std::foreach
使用a std::vector<int>
,但不能使用std::vector<bool>
?
内存优化是一个std::vector<bool>
(见这里)部分答案吗?
Inc*_*ble 22
问题源于这样一个事实:取消引用来自的迭代器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);
}
Run Code Online (Sandbox Code Playgroud)
演示.
尝试使用auto&
将再次触发编译错误,因为返回的代理不是左值,而是rvalue.因此,auto&&
比平时有更多的好处.