С двумя параметрами шаблона, вторым по умолчанию, я получаю то, что ожидаю, когда специализация приводит к явному предоставлению того, что в противном случае было типом по умолчанию для второго параметра.В этом случае специализация сформирована правильно, и поскольку она более специализирована, она выбирается.
Когда я повторяю это с одним аргументом шаблона, также по умолчанию, специализация, похоже, все еще хорошо сформирована, явно предоставляя типчто по умолчанию в базовом шаблоне.Однако в этом случае кажется, что это игнорируется и не считается более специализированным.Базовая версия всегда выбирается.
Может кто-нибудь объяснить, почему это происходит?
#include <iostream>
#include <utility>
#include <type_traits>
struct F1 { int operator()(); };
struct F2 {};
template<typename T, typename = int> struct A { constexpr static bool function_call_operator{false}; };
template<typename T> struct A<T, decltype(std::declval<T>()())> { constexpr static bool function_call_operator{true}; };
template<typename T = int> struct B { constexpr static bool function_call_operator{false}; };
template<typename T> struct B<decltype(std::declval<T>()())> { constexpr static bool function_call_operator{true}; };
void f0() {}
int main() {
std::cout << std::boolalpha;
std::cout << A<F1>::function_call_operator << std::endl; // true; OK
std::cout << A<F2>::function_call_operator << std::endl; // false; OK
std::cout << B<F1>::function_call_operator << std::endl; // false; why ?
std::cout << B<F2>::function_call_operator << std::endl; // false; OK
std::cout << std::noboolalpha;
}
Вот онлайн скомпилированная версия с компилятором C ++ 14.