Search code examples
c++templatesinitializer-list

Pass array of template size to function using an initializer list


I have a templated function, which takes an std::array of arbitrary size as an argument. It looks roughly like this:

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

I can call it e.g. like so:

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

and everything is fine.

Unfortunately I cannot call the function directly using an initializer list. This code:

foo({4, 5});

gives me the following error:

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

Is there a way to make my function work using an initializer list or something similar?


Solution

  • {/*..*/}has no type and so cannot be deduced in template function except for std::initializer_list<T> and for C-arrays T (&a)[N].

    So you have to

    • add overload to handle std::initializer_list<int> or 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()});
      }
      
    • or provide non deduced template parameter: foo<2>({4, 5});

    • or provide type to {} (easier with CTAD of C++17): foo(std::array{4, 5});