为什么匹配模板类上的部分类模板特化与另一个没有模板匹配的部分特化会产生歧义? [英] Why is a partial class template specialization on a matching template class ambiguous with another partial specialization without the template match?

查看:49
本文介绍了为什么匹配模板类上的部分类模板特化与另一个没有模板匹配的部分特化会产生歧义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题可能很难用标题中的句子来描述,但这里有一个最小的例子:

The question may be too hard to describe in on sentence in the title, but here is a minimal example:

#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;    
}

(也可在 Godbolt 上使用)

基本上,我们有一个基模板类 my_trait 采用两种类型(和一个用于特化目的的虚拟类型),具有两个部分特化:

Basically, we have a base template class my_trait taking two types (and a dummy type for specialization purposes), with two partial specializations:

  • 当两种类型相同时
  • 当这两种类型是同一类型的temped类模板的实例化
  • When the two types are the same
  • When the two types are instantiation of the temped class template for the same type

天真地,我们原以为第二个部分专业化不会与第一个有歧义,因为它感觉更专业",对 TU 的推导类型施加更多限制 在基本模板上.然而,主要编译器似乎同意我们的期望是错误的:为什么不认为它更专业?

Naïvely, we would have expected the second partial specialization not to be ambiguous with the first, as it feels "more specialized", putting more restriction on the deduced types for T and U on the base template. Yet major compilers seems to agree that we were wrong with our expectations: why is it not considered more specialized?

推荐答案

@super 现已删除的答案基本上是正确的.std::enable_if_t<...> 在偏序中不是 void;作为依赖类型,它原则上可以是完全任意的.对于偏序目的,它实际上被认为是一种完全独特的类型.

@super's now-deleted answer got this basically right. std::enable_if_t<...> is not void in partial ordering; as a dependent type it can in principle be something completely arbitrary. It effectively is considered a completely unique type for partial ordering purposes.

由于这种不匹配,偏序的推导在两个方向都失败了,并且特化不明确.

As a result of this mismatch, the deduction during partial ordering fails in both directions, and the specializations are ambiguous.

这篇关于为什么匹配模板类上的部分类模板特化与另一个没有模板匹配的部分特化会产生歧义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆