Мой вопрос: как правильно выбрать компилятор?какой алгоритм / метод / подход мне нужно продумать, чтобы понять, какой из них будет называться
Компилятор выбирает наиболее специализированную версию из доступных (и выдает ошибку, если возникает неоднозначность при выборе наиболеедоступна специализация).
Версия является более специализированной, чем другая, когда
1) все совпадения параметров шаблона, для более специализированных - также совпадения для менее специализированных
2) и есть совпадения для менее специализированных, которые не совпадают с более специализированными
В вашем случае у вас есть две версии canAssign
: основная и специализация.
Специализация, очевидно, более специализирована, чем основная версия, поэтому в случае совпадения версий ботов
canAssign<A,A>::result;
, поэтому компилятор выбирает специализацию.
В остальных случаях
canAssign<B,A>::result;
canAssign<B*,A*>::result;
соответствует только основная версия, поэтому компилятор выбирает основную версию.
Еще один пример для лучшего объясненияe точка: предположим, у вас есть шаблон foo
с двумя специализациями
template <typename, typename, typename>
struct foo
{ };
template <typename A, typename B>
struct foo<A, A, B>
{ };
template <typename A>
struct foo<A, A, A>
{ };
Вторая специализация является более специализированной, чем первая.
Фактически
1) все наборы параметров шаблона (обязательно все равные), соответствующие второму, обязательно соответствуют также первому (первый и второй равны)
2) существует хотя бы набор параметров шаблона (int
, int
, long
, например), который соответствует первому, но не второму.
Итак:
1) вторая специализация более специализированная, чем первая
2) первая специализация более специализированная, чем основная версия
То есть
foo<int, int, int>
соответствует всем версиям, поэтому компилятор выбирает вторую специализацию
foo<int, int, long>
соответствует основной версии и первой специализации, поэтому компилятор выбирает первую специализацию
foo<int, long, int>
соответствует только основной версии, поэтому компилятор выбирает основную версию.