Рассмотрим следующую программу:
template<template<typename ...> class>
struct foo {};
template<template<typename> class C>
struct foo<C> {};
int main() {}
Clang отклоняет его с ошибкой:
Частичная специализация шаблона шаблона не специализируется ни на одном аргументе шаблона
даже в последнем clang 7.0 HEAD, см. демо здесь. Однако gcc принимает его.
Обратитесь к [temp.class.spec], где указаны правила частичной специализации, я не мог найти ничего, что запрещало бы частичную специализация этого шаблона. В частности, специализация действительно более специализированная, сообщение об ошибке выглядит неверно.
EDIT:
Однако поведение gcc также является ненормальным, рассмотрим следующую программу:
#include <iostream>
template<template<typename ...> class>
struct foo { void show() { std::cout << "Primary.\n"; } };
template<template<typename> class C>
struct foo<C> { void show() { std::cout << "Specialized.\n"; } };
template<class...> struct bar {};
int main() {
foo<bar> f;
f.show();
}
Оказывается, что в этом случае gcc использует специализированную версию, см. здесь.
Теперь я хочу спросить:
-
- это частичная специализация, разрешенная стандартным?
-
какой компилятор прав? (один/все/ни один из них?)