是gcc中执行std::valarray的bug吗?

Is it a bug of the implementation of std::valarray in gcc?

我尝试了以下程序

#include <iostream>
#include <valarray>

int main( void ) 
{
    std::valarray<int> v1 = { 1, 2, 3, 4, 5 };
    std::valarray<int> v2 = { 1, 2, 3, 4, 5 };

    auto v3 = v1 * v2;

    for ( const auto &item : v3 ) std::cout << item << ' ';
    std::cout << '\n';

    return 0;
}

并收到一条错误消息,指出 v3 的适当函数 begin 在此语句中隐式使用

    for ( const auto &item : v3 ) std::cout << item << ' ';

找不到。

所以我尝试了下面的代码

#include <iostream>
#include <valarray>
#include <type_traits>

int main( void ) 
{
    std::valarray<int> v1 = { 1, 2, 3, 4, 5 };
    std::valarray<int> v2 = { 1, 2, 3, 4, 5 };

    auto v3 = v1 * v2;

    std::cout << std::is_same<std::valarray<int>, decltype( v3 )>::value << '\n';
    return 0;
}

得到结果

0

但是当这个语句

auto v3 = v1 * v2;

改为

std::valarray<int> v3 = v1 * v2;

那么输出是

1

std::valarray<int>operator * 声明如下

template<class T> valarray<T> operator* (const valarray<T>&, const valarray<T>&);

那么是不是std::valarray<int>实现的bug?

这不是错误。 std::valarray::operator* 实际上不必 return 一个 std::valarray 因为它允许使用表达式模板。这意味着它可以 return 具有以下属性的类型:

  • All const member functions of std::valarray are provided.
  • std::valarray, std::slice_array, std::gslice_array, std::mask_array and std::indirect_array can be constructed from the replacement type.
  • All functions accepting an argument of type const std::valarray& except begin() and end() (since C++11) should also accept the replacement type.
  • All functions accepting two arguments of type const std::valarray& should accept every combination of const std::valarray& and the replacement type.
  • The return type does not add more than two levels of template nesting over the most deeply-nested argument type.

强调我的source

因此,您需要将 return 显式捕获为 std::valarray,以便可以调用 std::begin 的特化。