Для краткости пример кода опускает детали.Развернем пример:
template<class T, class U = T> class B { /* ... */ };
template<template<class> class P> class X {
P<int, int> pii; // error: P has been declared to take only one argument
P<int> pi; // OK
P<char> pc; // OK
/* ... */
};
X<B> xb; // OK in C++17; ill formed in C++14
Последняя строка разрешает P<int>
как B<int>
.Это правда, что последнее означает B<int, int>
, но с учетом параметра по умолчанию, B<int>
- это однозначный способ записать это.
В принципе, насколько я знаю, не было причины C++ 14 не мог этого понять, но цепочка рассуждений была слишком сложной для C ++ 14.Три года спустя C ++ 17 это понимает.
Кстати, компилятор Clang C ++ предлагает опцию -frelaxed-template-template-args
для решения этой проблемы.Если вы используете шаблоны шаблонов в Clang, вы можете использовать эту опцию.(@ Rakete1111 признан тем, что привлек внимание к опции Clang.)