在 std::valarray<T> 上使用 .sum() 和 +=
Using .sum() and += on std::valarray<T>
我正在使用类型 std::valarray<std::valarray<double>>
并希望对每个包含的 valarrays 元素进行明智的求和,留下 std::valarray<double>
.
C++ 文档指出,只要运算符 +=
是为类型 T 定义的,运算符 .sum() 就可以应用于 std::valarray<T>
。我下面的代码(方法 1)尝试应用这对 std::valarray<std::valarray<double>>
,但结果似乎是胡说八道。
但是,如果我使用 +=
运算符(方法 2)手动执行此操作,我会得到我想要的结果。但 method2 有效的事实似乎暗示运算符 +=
是为类型 std::valarray<double>
定义的,因此 method1 使用 .sum()。应该管用。我真的不明白这里发生了什么......
我的代码:
#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
std::valarray
的 sum
方法要求为其值类型定义 operator+=
(在您的情况下,std::valarray
),但 std::valarray
也要求它是 default-constructible(来自 "Numeric" 概念要求)。
这允许 sum
方法在没有 operator+
的情况下工作,首先 default-constructing 一个元素,然后添加每个包含的元素 operator+=
.
虽然它没有在任何地方定义,但据我所知,它可能是这样工作的。
T sum() const {
T result;
for (auto& it : elements) {
result += it;
}
return result;
}
valarray 的 valarray (std::valarray<std::valarray>
) 的问题是 default-constructed valarray 是空的。当 operator+=
与一个空的 valarray 和一个 non-empty 一起应用时,它会导致未定义的行为 ("The behavior is undefined if size() != v.size()
")。结果你可能会得到一个空的 valarray(但你可能会得到任何东西)。
您可以使用 std::accumulate
。它需要一个初始值作为第三个参数,它解决了这个问题。
std::accumulate(std::begin(data), std::end(data), std::valarray<double>(data[0].size()))
PS:别问我为什么std::valarray
没有方法begin
和end
.
我正在使用类型 std::valarray<std::valarray<double>>
并希望对每个包含的 valarrays 元素进行明智的求和,留下 std::valarray<double>
.
C++ 文档指出,只要运算符 +=
是为类型 T 定义的,运算符 .sum() 就可以应用于 std::valarray<T>
。我下面的代码(方法 1)尝试应用这对 std::valarray<std::valarray<double>>
,但结果似乎是胡说八道。
但是,如果我使用 +=
运算符(方法 2)手动执行此操作,我会得到我想要的结果。但 method2 有效的事实似乎暗示运算符 +=
是为类型 std::valarray<double>
定义的,因此 method1 使用 .sum()。应该管用。我真的不明白这里发生了什么......
我的代码:
#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
std::valarray
的 sum
方法要求为其值类型定义 operator+=
(在您的情况下,std::valarray
),但 std::valarray
也要求它是 default-constructible(来自 "Numeric" 概念要求)。
这允许 sum
方法在没有 operator+
的情况下工作,首先 default-constructing 一个元素,然后添加每个包含的元素 operator+=
.
虽然它没有在任何地方定义,但据我所知,它可能是这样工作的。
T sum() const {
T result;
for (auto& it : elements) {
result += it;
}
return result;
}
valarray 的 valarray (std::valarray<std::valarray>
) 的问题是 default-constructed valarray 是空的。当 operator+=
与一个空的 valarray 和一个 non-empty 一起应用时,它会导致未定义的行为 ("The behavior is undefined if size() != v.size()
")。结果你可能会得到一个空的 valarray(但你可能会得到任何东西)。
您可以使用 std::accumulate
。它需要一个初始值作为第三个参数,它解决了这个问题。
std::accumulate(std::begin(data), std::end(data), std::valarray<double>(data[0].size()))
PS:别问我为什么std::valarray
没有方法begin
和end
.