问题可能很难在标题中的句子中描述,但这是一个最小的示例:
#include <iostream>
#include <type_traits>
template <class T, class U, class Enabler>
struct my_trait : std::false_type
{};
template <class T, class U>
struct my_trait<T, U,
std::enable_if_t<std::is_same<T, U>::value>> : std::true_type
{};
template <class T>
class temped
{};
template <class T>
struct my_trait<temped<T>, temped<T>, void> : std::false_type
{};
template <class T, class U>
using trait_t = my_trait<T, U, void>;
int main()
{
std::cout << std::boolalpha;
std::cout << trait_t<int, float>::value << std::endl; // false
std::cout << trait_t<int, int>::value << std::endl; // true
// Compilation error: Ambiguous
//std::cout << trait_t<temped<int>, temped<int>>::value << std::endl;
return 0;
}
[基本上,我们有一个基本模板类my_trait
,它具有两种类型(为了专业化目的是一个虚拟类型),具有两个部分专业化:
temped
类模板的实例时[天真的,我们希望第二部分专业化与第一部分专业化没有歧义,因为它感觉“更专业”,对基础模板上T
和U
的推导类型施加了更多限制。但是主要的编译器似乎同意我们错了我们的期望:为什么它不被认为更专业?
tempted<T>
的可能性范围比T
窄。