integer_sequence and default parameter value

755 views Asked by At

Straightforward using of default parameter value to generate integer sequence as follows lead to hard error (complier clang-3.6):

#include <iostream>
#include <utility>

#include <cstdlib>

template< std::size_t M, std::size_t N > // say M - arity, N - number of types
struct test
{

    template< std::size_t ...i >
    void
    operator () (std::index_sequence< i... > = std::make_index_sequence< M >{}) const
    {
        std::size_t indices[M];
        for (std::size_t & m : indices) {
            m = 0;
        }
        for (;;) {
            (std::cout << ... << indices[i]) << std::endl;
            std::size_t m = 0;
            for (;;) {
                std::size_t & n = indices[m];
                ++n;
                if (n != N) {
                    break;
                }        
                n = 0; 
                if (++m == M) {
                    return;
                }
            }
        }
    }

};

int
main()
{
#if 0
    test< 3, 3 >{}(); // hard error
#else
    test< 3, 3 >{}(std::make_index_sequence< 3 >{}); // ugly workaround
#endif
    return EXIT_SUCCESS;
}

It looks strange, because simple substitution works as intended.

Why is it so? Why default parameter cannot be assigned in above a case, but explicit assignment works?

Appending const & or && to parameter type does nothing.

1

There are 1 answers

3
David G On BEST ANSWER

Template arguments can't be deduced from default arguments. This is why we typically delegate to a helper function before building the sequence:

void operator()() const {
    helper(std::make_index_sequence<M>{});
}

template<std::size_t... i>
void helper(std::index_sequence<i...>) const;