Valarray划分其元素
valarray divide its element
当我将一个 valarray 除以它的第一个元素时,只有第一个元素变成 1,其他元素保持其原始值。
#include <iostream>
#include <valarray>
using namespace std;
int main() {
valarray<double> arr({5,10,15,20,25});
arr=arr/arr[0]; // or arr/=arr[0];
for(int value:arr)cout << value << ' ';
return 0;
}
实际输出为:
1 10 15 20 25
预期输出为:
1 2 3 4 5
为什么实际输出与预期不符?
我将 g++(4.8.1) 与 -std=c++11 一起使用
这个工作:
#include <iostream>
#include <valarray>
using namespace std;
int main() {
valarray<double> arr({5,10,15,20,25});
auto v = arr[0];
arr=arr/v; // or arr/=arr[0];
for(int value:arr)cout << value << ' ';
return 0;
}
问题是您正在尝试使用同时修改的数组中的值(arr[0]
arr
)。
直观地说,一旦你通过执行arr[0]/arr[0]
更新了arr[0]
,它包含什么价值?
好吧,这就是从现在开始将用于除以其他值的值......
请注意,这同样适用于arr/=arr[0]
(首先,arr[0]/arr[0]
发生在 for 循环或类似的东西中,而不是所有其他)。
另请注意,从文档中operator[]
std::valarray
返回一个T&
。这证实了上面的假设:它作为迭代的第一步转向1
,然后所有其他操作都是无用的。
通过简单地复制它就可以解决问题,如示例代码所示。
发生这种情况的原因的详细信息是由于valarray
中使用的实现技巧来提高性能。libstdc++ 和 libc++ 都使用表达式模板来获取valarray
操作的结果,而不是立即执行操作。这是 [valarray.syn] p3 在C++标准中明确允许的:
任何返回
valarray<T>
的函数都可以返回其他类型的对象,前提是所有valarray<T>
的常量成员函数也适用于此类型。
在您的示例中发生的情况是,arr/arr[0]
不会立即执行除法,而是返回一个对象,例如 _Expr<__divide, _Valarray, _Constant, valarray<double>, double>
该对象具有对arr
的引用和对arr[0]
的引用。将该对象分配给另一个valarray
执行除法运算,并将结果直接存储到分配的左侧(这样可以避免创建临时valarray
来存储结果,然后将其复制到左侧)。
因为在示例中,左侧是同一对象,arr
,这意味着一旦使用结果更新arr
中的第一个元素,对存储在表达式模板中的arr[0]
的引用将引用不同的值。
换句话说,最终结果是这样的:
valarray<double> arr{5, 10, 15, 20, 25};
struct DivisionExpr {
const std::valarray<double>& lhs;
const double& rhs;
};
DivisionExpr divexpr = { arr, arr[0] };
for (int i = 0; i < size(); ++i)
arr[i] = divexpr.lhs[i] / divexpr.rhs;
for循环的第一次迭代将arr[0]
设置为arr[0] / arr[0]
即 arr[0] = 1
,然后所有后续迭代都将设置arr[i] = arr[i] / 1
这意味着值不会更改。
我正在考虑对 libstdc++ 实现进行更改,以便表达式模板将直接存储double
而不是保存引用。这意味着arr[i] / divexpr.rhs
将始终评估arr[i] / 5
,而不是使用更新的值 arr[i]
。
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用strcpy将char数组的元素复制到另一个数组
- 使用不带参数的函数访问结构元素
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- C++如何通过用户输入删除列表元素
- lower_bound()返回最后一个元素
- 基于多个条件处理地图中的所有元素
- 调整大小后指向元素值的指针unordered_map有效?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 使用函数"remove"删除重复元素
- 具有最大子序列大小的序列,每个元素都相同
- 将一系列已排序的元素划分为相邻组
- c++中向量中元素的划分
- 一个数组可以划分的最大子数组,使得不同子数组中任意两个元素的 GCD 始终为 1?
- 删除每个元素可以将数组中的另一个元素划分
- Valarray划分其元素
- 将字符串划分为结构中的元素
- 将容器中的每个元素划分为给定的数(c++)
- 根据条件划分数组中的元素