Это ошибка реализации std :: valarray в gcc? - PullRequest
4 голосов
/ 25 сентября 2019

Я попробовал следующую программу

#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;
}

и получил сообщение об ошибке, что соответствующая функция begin для v3, неявно используемая в этом операторе

    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

operator * для std::valarray<int> объявлен следующим образом

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

Так что этоошибка реализации std::valarray<int>?

1 Ответ

5 голосов
/ 25 сентября 2019

Это не ошибка.std::valarray::operator* на самом деле не должен возвращать std::valarray, потому что ему разрешено использовать шаблоны выражений.Это означает, что он может возвращать тип со следующими свойствами:

  • Предоставляются все функции-константы std::valarray.
  • std::valarray, std::slice_array,std::gslice_array, std::mask_array и std::indirect_array могут быть созданы из типа замены.
  • Все функции, принимающие аргумент типа const std::valarray&, кроме begin() и end() (так как C ++11) также должен принимать тип замены .
  • Все функции, принимающие два аргумента типа const std::valarray&, должны принимать каждую комбинацию const std::valarray& и типа замены.
  • ВозвратТип не добавляет более двух уровней вложенности шаблонов к наиболее глубоко вложенному типу аргумента.

выделение шахты источник

Из-за этого вам необходимо явно зафиксировать возвращаемое значение как std::valarray, чтобы можно было вызвать специализацию для std::begin.

...