mardi 23 août 2016

Template arguments deduction for parameter type of function pointer involving non-deduced parameter pack

This is similar to the question, but a more specific case. This time, no compiler work as expected.

template<class T>
struct nondeduced
{
    using type = T;
};

template<class T>
using nondeduced_t = typename nondeduced<T>::type;

template<class... T, class U>
void f(void(*)(nondeduced_t<T>..., U)) {}

void g(int, char) { }

int main()
{
    f<int>(g); // error?
}

In the above example, the parameter pack T cannot be deduced, but the compiler should be able to deduce U after explicit arguments substitution for pack T (i.e. single int in this case).

The above is expected to work without the nondeduced_t trick as well:

template<class... T, class U>
void f(void(*)(T..., U)) {}

Because the parameter pack T is already in non-deduced context according to [temp.deduct.type]p5

The non-deduced contexts are:

  • A function parameter pack that does not occur at the end of the parameter-declaration-list.

Unfortunately, no compiler I tested (g++/clang) accept the code. Notably something like below works on both g++ & clang.

template<class... T>
void f(void(*)(nondeduced_t<T>..., char)) {}

And again, this doesn't work on both:

template<class... T>
void f(void(*)(T..., char)) {}

Is my expectation wrong?

Aucun commentaire:

Enregistrer un commentaire