嵌套std::for_each与Lambda函数引发C2664编译错误的问题咨询
嵌套std::for_each与Lambda函数引发C2664编译错误的问题咨询
嗨,我来帮你拆解下这个编译报错的根源,其实问题出在你用的std::vector<std::vector<bool>>上——这可是C++标准库出了名的“坑点”容器!
咱们先理清楚核心矛盾:
std::vector<bool>是标准库为了节省空间做的特殊特化版本,它并没有把每个bool值存在单独的内存位置,而是把多个bool打包到一个字节里。为了让你能像操作普通bool引用那样操作它的元素,库里面用了一个叫std::vector<bool>::reference的代理对象,代替了真正的bool&。- 你的内层Lambda用了
auto& free作为参数,这里的auto&会被编译器推导成非常量左值引用。但std::for_each遍历std::vector<bool>时,迭代器解引用返回的是std::vector<bool>::reference类型的临时对象,而C++里临时对象是不能绑定到非const的左值引用的,这就直接触发了C2664类型不匹配的错误。
那怎么解决这个问题呢?给你几个实用的方案:
- 方案1:修改Lambda的参数类型
把内层Lambda的参数改成auto&& free(完美转发引用),或者直接用auto free。这两种方式都能正确绑定到代理对象,而且赋值操作free = false也能正常工作,因为代理对象重载了赋值运算符:std::for_each(grid.begin(), grid.end(), [](auto& row) { std::for_each(row.begin(), row.end(), [](auto&& free) { free = false; }); }); - 方案2:替换掉
std::vector<bool>
如果你不想和这个代理对象打交道,直接用std::vector<std::vector<char>>或者std::vector<std::bitset<4>>来代替。比如std::vector<std::vector<char>> grid(4, std::vector<char>(4, true)),这样每个元素都是真正的char类型,你的原代码就能正常编译,因为char&是合法的左值引用,和std::for_each传递的元素完全匹配。 - 方案3:明确指定参数类型
把内层Lambda的参数直接写成std::vector<bool>::reference free,这样也能匹配,但可读性会差一些,不推荐除非你特别清楚这个代理对象的行为。
下次再用std::vector<bool>可得小心啦,它的行为和普通的vector差不少呢!
内容来源于stack exchange
相关产品推荐
相关产品推荐

