jeudi 2 février 2017

Weird behaviour variadic argument template

I tasked myself in writing a function that would accept generic STL containers, and came up with this design:

template<template<class, class...> class C,
         class... A,
         class T = typename C<A...>::value_type>
void wrong( std::vector<C<T, A...>>& indexes, std::vector<T>& resultSet ) {
    resultSet.push_back(indexes[0][0]);
}

That was my first attempt which was blatantly wrong but that worked so I skipped on that then I spotted the mistake during code review and wrote the following which is more correct

template<template<class...> class C,
         class... A,
         class T = typename C<A...>::value_type>
void correct( std::vector<C<A...>>& indexes, std::vector<T>& resultSet ) {
    resultSet.push_back(indexes[0][0]);
}

Let's say that the above code is used in the following:

int main()
{
    std::vector<int> v1 {1,2}, v2{3,4};
    std::vector<std::vector<int>> sets {v1, v2};
    std::vector<int> r;

    wrong(sets, r);
    std::cout << r.back() << std::endl;
    r.clear();

    correct(sets, r);
    std::cout << r.back() << std::endl;

}

Compiling I get the same (and intended) behaviour but I feel that the first wrong function should have failed since the "C" type takes three types as argument being int, int, Allocator. The behavior of the second one matches my understanding of templates.

The question is: what is going on in template deduction of the above?

Aucun commentaire:

Enregistrer un commentaire