我使用的是std::valarray<std::valarray<double>>
类型,并且希望对每个包含的valarrays元素进行求和,以留下std::valarray<double>
。
C ++文档声明运算符.sum()可以应用于std::valarray<T>
,只要为类型T定义了运算符+=
。我的代码(方法1)尝试将此应用于std::valarray<std::valarray<double>>
,但结果似乎是无稽之谈。
但是如果我手动执行此操作,使用+=
运算符(method2),我会得到我想要的结果。但是,method2的工作原理似乎意味着使用.sum()为类型+=
定义了运算符std::valarray<double>
,因此定义了该方法1。应该管用。我真的无法理解这里发生的事情......
我的代码:
#include <iostream>
#include <valarray>
// Attempt to use .sum() operator
std::valarray<double> method1(const std::valarray<std::valarray<double>>& data) {
return data.sum();
}
// Manual summation using += operator
std::valarray<double> method2(const std::valarray<std::valarray<double>>& data) {
std::valarray<double> sum(data[0].size());
for (size_t i{0}; i < data.size(); i++) {
sum += data[i];
}
return sum;
}
// Display size and elements
void showData(const std::valarray<double> data) {
std::cout << "Size = " << data.size() << "\n";
std::cout << "Data = ";
for (size_t i{0}; i < data.size(); i++) {
std::cout << data[i] << " ";
}
std::cout << "\n\n";
}
int main() {
std::valarray<std::valarray<double>> data{{1,2},{3,4}};
showData(method1(data));
showData(method2(data));
}
我的输出:
Size = 0
Data =
Size = 2
Data = 4 6
答案 0 :(得分:1)
sum
std::valarray
方法需要为其值类型定义operator+=
(在您的情况下为std::valarray
),但std::valarray
也需要sum
默认构造(来自&#34; Numeric&#34;概念要求)。
这允许operator+
方法在没有operator+=
的情况下工作,首先默认构造一个元素,然后使用T sum() const {
T result;
for (auto& it : elements) {
result += it;
}
return result;
}
添加每个包含的元素。
虽然它没有在任何地方定义,据我所知,它可能会像这样。
std::valarray<std::valarray>
valarray(operator+=
)的valarray的问题是默认构造的valarray是空的。当std::accumulate(std::begin(data), std::end(data), std::valarray<double>(data[0].size()))
应用空的valarray和非空的valarray时,会导致未定义的行为("The behavior is undefined if size() != v.size()
")。你可能得到的结果是一个空的valarray(但你可能得到任何东西)。
您可以使用的是std::accumulate
。它需要一个初始值作为第三个参数,它可以解决问题。
std::valarray
PS:不要问我为什么begin
没有方法end
和{{1}}。