Template template partial specialization only working with -std=c++1z with g++

纵饮孤独 提交于 2019-12-05 05:44:13

This is a result of the adoption of P0522 in C++17, whose motivation was, from the example:

template <template <int> class> void FI();
template <template <auto> class> void FA();
template <auto> struct SA { /* ... */ };
template <int> struct SI { /* ... */ };
FI<SA>();  // OK; error before this paper
FA<SI>();  // error

template <template <typename> class> void FD();
template <typename, typename = int> struct SD { /* ... */ };
FD<SD>();  // OK; error before this paper (CWG 150)

Previously, the wording in [temp.arg.template] required template template parameters to match in kind exactly. So given:

template <template <class > class P> class X;

template <class T> class A;
template <class T, class U=T> class B;
template <class... > class C;

X<A> is clearly okay, but X<B> is ill-formed because B takes two template parameters (regardless if one is defaulted!) and X<C> is ill-formed because P expects one template parameter and C takes a pack (even if you could form a C with only a single parameter!)

The new wording loosens the idea of a match to one which makes more sense - if the template template-parameter is at least as specialized as the argument. That makes X<B> and X<C> both work.

Hence, in C++17, X<std::vector<double>> should pick the specialization. But before C++17, it should pick the primary. gcc is doing the right thing.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!