std::valarray<int*>使用operator +=报错的原因及解决方法咨询
为什么
std::valarray<int*>的+=1会报错?我来帮你解析并解决 这个问题挺有意思的,先拆解一下核心矛盾:明明单独给每个指针元素vi[0] +=1完全合法,为什么批量用valarray的+=操作就报错了?
错误原因分析
先对比两个例子的差异:
- 对于
std::valarray<std::string>,vs += "hello"能正常工作,是因为std::string自带operator+=接受const char*,而valarray的标量版本operator+=会遍历每个元素,对每个std::string对象调用对应的operator+=,完全符合语法要求。 - 但对于
std::valarray<int*>,vi +=1的问题出在**valarray模板操作符的匹配逻辑**上:- 理论上,
valarray有一个标量版本的operator+=,应该遍历每个元素执行elem += scalar(这里就是int* += int,指针算术运算合法)。但某些编译器的valarray实现中,这个标量版本的重载匹配出现了问题,导致编译器无法正确识别。 - 当标量版本匹配失败后,编译器会尝试另一个重载:两个
valarray的元素-wise相加(valarray<T>& operator+=(const valarray<T>&))。此时编译器会试图把1(int类型)隐式转换成valarray<int*>,虽然这种转换并不合理,但编译器仍会尝试生成代码。最终,它会执行int* + int*的操作——而C++中指针之间是不允许相加的(只能相减),于是就出现了你看到的错误:invalid operands of types 'int*' and 'int*' to binary 'operator+'。
- 理论上,
解决办法
既然直接用vi +=1走不通,我们可以用两种方式实现批量给每个指针加1的需求:
方法1:用std::for_each遍历元素
通过迭代器遍历valarray的每个元素,手动执行指针加法:
#include <algorithm> // 需要包含这个头文件 // ... 你的其他代码 ... std::for_each(std::begin(vi), std::end(vi), [](int*& ptr) { ptr += 1; // 对每个指针执行+=1操作 });
方法2:用std::valarray::apply成员函数
valarray的apply方法会对每个元素应用指定函数,并返回新的valarray,我们可以用它生成每个指针加1后的结果,再赋值给原数组:
vi = vi.apply([](int* ptr) { return ptr + 1; // 返回加1后的指针 });
这两种方法都能达到你想要的效果,同时避开了valarray操作符重载的匹配问题。
内容的提问来源于stack exchange,提问作者bou
相关产品推荐
相关产品推荐

