Тема выглядит немного запутанно, однако я не знаю, как ее сформулировать более правильно, извините =)
Давайте посмотрим следующий код
#include <iostream>
template<typename T>
void f(T value) {
std::cout << "f<T>" << std::endl;
}
template<>
void f(int value) {
std::cout << "f<int>" << std::endl;
}
template<typename T>
struct S {
using type = T;
};
template<typename T>
void f(typename S<T>::type value) {
std::cout << "f<S<T>>" << std::endl;
};
int main() {
f(123);
f<int>(123);
}
Вывод
$ ./testgcc
f<int>
f<S<T>>
Итак, вопрос в том, почему первый вызов приводит к специализации f<int>
, а второй с явным аргументом шаблона int приводит к вызову "templated" f<S<int>>()
? Есть ли в стандарте правило, в котором говорится, как создавать шаблоны в таких ситуациях?
Заранее спасибо!
PS Протестировано с различными версиями g cc и clang. - поведение такое же. У меня нет windows системы для тестирования с MSV C, однако я тестировал на Godbolt и MSV C приводит к следующему коду:
_main PROC
; ....
push 123 ; 0000007bH
call void f<int>(int) ; f<int>
add esp, 4
push 123 ; 0000007bH
call void f<int>(int) ; f<int>
; ...
Так что MSV C звонит f<int>
в обоих случаях. Задокументировано ли это поведение как реализация, определенная ?