C++11 使用.sum()和+;=关于std::valarray<;T>;

C++11 使用.sum()和+;=关于std::valarray<;T>;,c++11,stl,containers,valarray,C++11,Stl,Containers,Valarray,我正在使用类型std::valarray,并希望对包含的每个valarray元素进行求和,以留下一个std::valarray C++文档说明,运算符.SUME()可以应用到 STD::ValSux只要操作符 += < /C> >为T类型定义。我的代码下面(Mult1)试图将其应用到 STD::ValSuth,但结果似乎是废话。 但是,如果我使用+=操作符(方法2)手动执行此操作,我会得到想要的结果。但是method2工作的事实似乎意味着操作符+=是为类型std::valarray定义的,因此

我正在使用类型
std::valarray
,并希望对包含的每个valarray元素进行求和,以留下一个
std::valarray

C++文档说明,运算符.SUME()可以应用到<代码> STD::ValSux只要操作符<代码> += < /C> >为T类型定义。我的代码下面(Mult1)试图将其应用到<代码> STD::ValSuth,但结果似乎是废话。 但是,如果我使用

+=
操作符(方法2)手动执行此操作,我会得到想要的结果。但是method2工作的事实似乎意味着操作符
+=
是为类型
std::valarray
定义的,因此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));
}

std::valarray
sum
方法要求为其值类型定义
运算符+=
(在您的情况下,
std::valarray
),但
std::valarray
也要求它是默认可构造的(根据“数字”概念要求)。 这允许
sum
方法在不使用
运算符+
的情况下工作,默认情况下,首先构造一个元素,然后使用
运算符+=
添加每个包含的元素

虽然它在任何地方都没有定义,但据我所知,它可能是这样工作的

T sum() const {
    T result;
    for (auto& it : elements) {
        result += it;
    }
    return result;
}
valarray的valarray(
std::valarray
)的问题是默认构造的valarray为空。当
操作符+=
与空数组和非空数组一起应用时,会导致未定义的行为()。因此,您可能会得到一个空的valarray(但您可能会得到任何东西)

你可以用的是。它需要一个初始值作为解决问题的第三个参数

std::accumulate(std::begin(data), std::end(data), std::valarray<double>(data[0].size()))
std::accumulate(std::begin(数据)、std::end(数据)、std::valarray(数据[0].size())


PS:不要问我为什么
std::valarray
没有方法
begin
end

这似乎是特定于某些编译器的,请指定使用哪个编译器和哪些选项。实际上,使用
g++-D_GLIBCXX_DEBUG
编译时会给出:“std::valarray&std::valarray::operator+=(const std::valarray&)[带_Tp=double]:断言“_M_size==_v._M_size”失败
std::accumulate(std::begin(data), std::end(data), std::valarray<double>(data[0].size()))