Передать массив размера шаблона в функцию, используя список инициализатора - PullRequest
2 голосов
/ 23 апреля 2020

У меня есть шаблонная функция, которая принимает std::array произвольного размера в качестве аргумента. Это выглядит примерно так:

template <size_t n>
void foo(const std::array<int, n>& numbers) {
    for (const auto & number: numbers) {
        // ... do stuff ...
    }
}

Я могу назвать это, например, так:

std::array<int, 2> ints = {4, 5};
foo(ints);

и все в порядке.

К сожалению, я не могу вызвать функцию напрямую используя список инициализаторов. Этот код:

foo({4, 5});

выдает мне следующую ошибку:

error: no matching member function for call to 'foo'
note: candidate template ignored: couldn't infer template argument 'n'

Есть ли способ заставить мою функцию работать, используя список инициализаторов или что-то подобное?

1 Ответ

5 голосов
/ 23 апреля 2020

{/*..*/} не имеет типа и поэтому не может быть выведен в функции шаблона, за исключением std::initializer_list<T> и C -массивов T (&a)[N].

Так что вам нужно

  • добавить перегрузку для обработки std::initializer_list<int> или C -array.

    // span (C++20) has constructor from std::array :)
    void foo(const std::span<int>& numbers) {
        for (const auto & number: numbers) {
            // ... do stuff ...
        }
    }
    
    void foo(std::initializer_list<int> numbers) {
        foo(std::span{numbers.begin(), numbers.size()});
    }
    
  • или предоставить необработанный параметр шаблона: foo<2>({4, 5});

  • или укажите тип {} (проще с CTAD из C ++ 17): foo(std::array{4, 5});

...