[英]Why is a partial class template specialization on a matching template class ambiguous with another partial specialization without the template match?
这个问题可能很难用标题中的句子来描述,但这里有一个最小的例子:
#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;
}
基本上,我们有一个基本模板 class my_trait
采用两种类型(以及用于专业化目的的虚拟类型),具有两个部分专业化:
temped
class 模板的实例化时天真地,我们本以为第二个部分特化不会与第一个模棱两可,因为它感觉“更特化”,对基本模板上T
和U
的推导类型施加了更多限制。 然而,主要编译器似乎同意我们的期望是错误的:为什么不认为它更专业?
@super 现在已删除的答案基本上是正确的。 std::enable_if_t<...>
在部分排序中不是void
的; 作为依赖类型,它原则上可以是完全任意的。 它实际上被认为是用于部分排序目的的完全独特的类型。
由于这种不匹配,偏序期间的推导在两个方向上都失败了,并且特化是模棱两可的。
这是因为
std::enable_if_t<std::is_same_v<temped<int>, temped<int>>
解决无效然后你有
my_trait<temped<int>, temped<int>, void>::value
模棱两可地定义为真或假。 如果您更改类型 enable_if 解析为,比如说 bool,一切编译正常
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.