我有以下代码片段,它接受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 /../../../../包括/ C ++ / 7.2.0 / bits / stl_algo.h:3884:2:错误:没有匹配函数来调用类型'的对象(lambda at :7:18)'
__f(*__first); ^~~
:10:10:注意:在功能模板的实例化中 专业化'std :: for_each:7:18)&gt;'请求
std::for_each(list.begin(), list.end(),reset); ^
:7:18:注意:候选功能不可行:不知道 从'std :: _ Bit_iterator :: reference'转换(aka 'std :: _ Bit_reference')到'bool&amp;'第一个参数
auto reset = [](bool & element){element = false;}; ^
:7:18:注意:'void(*)(bool&amp;)'的转换候选人
为什么std::foreach
适用于std::vector<int>
,但不适用于std::vector<bool>
?
std::vector<bool>
(见here)部分答案的内存优化是什么?
答案 0 :(得分:22)
问题源于这样一个事实,即取消引用来自std::vector<bool>
的迭代器并不会返回bool&
,而是返回代理对象。因此,it is not regarded as stl container(感谢@KillzoneKid)。
在参数列表中使用auto element
。通常,如果您不关心类型,请在lambda参数列表中使用auto&&
。
#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&
将trigger compilation error again,因为返回的代理不是左值,而是右值。因此,auto&&
比平时有更多的好处。