paulm paulm - 1 month ago 19
C++ Question

Deduce std::array size?

In the following code:

template<size_t N>
int b(int q, const std::array<int, N>& types)
{
int r = q;
for (int t : types)
{
r = r + t;
}
return r;
}

int main()
{
b<2>(9, { 2,3 });
}


How can I avoid having to specify 2 in the call to b for N? Why can't this type be automatically deduced? With out it I get the error:


'b': no matching overloaded function found 'int b(int,const
std::array &)': could not deduce template argument for 'N'

Answer

Template argument deduction relies on direct type matching between actual argument and formal argument. The actual argument is an initializer list. It doesn't match the array type (at best it could match the internal raw array in a std::array, but the language rules don't support that).

Instead you can just use a raw array, to wit:

#include <stddef.h>
#include <array>

template<size_t N>
int b(int q, int const (&types)[N] )
{
    int r = q;
    for (int t : types)
    {
        r = r + t;
    }
    return r;
}

int main()
{
    b( 9, { 2, 3 } );
}

Or, if you don't absolutely need N at compile time, you can use a std::initializer_list.

There are also many other possibly relevant approaches (e.g. variadic template function, or defining an operator to build up a std::vector), but it's difficult to say what would suit your undisclosed purpose.

Comments