Только функция-член является шаблонной, что означает, что вы должны использовать только один template<...>
. Но это также не решит проблему, так как вы не можете частично специализировать функцию.
Обычным способом решения проблемы является перегрузка, а не специализация (специализация шаблонных функций не так уж полезна).
struct test {
template <typename Container>
void f( Container& ) { ... }
template <typename T, int N>
void f( std::array<T,N>& ) { ... }
};
Обратите внимание, что разница в том, что это две отдельные функции шаблона (а не специализация).
РЕДАКТИРОВАТЬ : после обновления
Обновление вопроса полностью меняет проблему. Проблема, которую вы видите, состоит в том, что аргумент второй версии является зависимым именем, и как таковой он не выводим. Учитывая вызов функции, компилятор не может определить, какой тип T и интегральная константа N должны соответствовать этому конкретному экземпляру. Рассмотрим другой пример:
template <typename T>
struct inner_int {
typedef int type;
};
template <typename T>
void foo( typename inner_int<T>::type ) {
}
int main() {
foo( inner_int<double>::type() );
}
Когда компилятор обрабатывает вызов в main
, он создает шаблон и извлекает тип, из которого он создает временный, а затем пытается решить, что делать с foo
, но в то время он знает только что он вызывается со значением int
r ... исходный inner<double>::type
пропал, теперь он просто foo( int() )
, и компилятор должен попытаться создать экземпляр inner_int
со всеми возможными типами, чтобы определить, является ли какой-либо из они подходят, и в худшем случае, как указано выше, многие подойдут.