8

I was actually surprised that both gcc and clang accept this code:

#include <iostream>
#include <vector>
#include <type_traits>

template <class T, template <class, class = T> class TT, class Y>
T foo(TT<Y>) {
}

int main() {
    static_assert(std::is_same<decltype(foo(std::vector<int>{})), std::allocator<int>>::value);
}

Are gcc and clang right that the values of the default template template parameters are deduced context or is it compilers extension?

W.F.
  • 13,888
  • 2
  • 34
  • 81

1 Answers1

5

When you write

template <class T, template <class, class = T> class TT, class Y>
T foo(TT<Y>);

it is equivalent to

template <class T, template <class, class = T> class TT, class Y>
T foo(TT<Y, T>);

So T can be deduced.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • 1
    That makes sense, however it still looks like a compilers trick, is it guaranteed by standard? – W.F. Dec 07 '16 at 21:00
  • @W.F. Maybe it's implied from § 14.3.3/3? (N4296) – AndyG Dec 07 '16 at 21:39
  • @AndyG it looks like it could explain it, let me analyse it a bit more... – W.F. Dec 07 '16 at 21:47
  • @AndyG I'm not sure. My understanding of the fragment is that it the the template template parameter matches if the classes of the template parameters match... I think it is referring to the type/template template/non-type template parameters and no default values of any kind of parameters... but I might misunderstood that fragment as I'm not a native... :( – W.F. Dec 07 '16 at 21:56