繁体   English   中英

为什么匹配模板 class 上的部分 class 模板特化与没有模板匹配的另一个部分特化模棱两可?

[英]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;    
}

也可在 Godbolt 上找到

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

  • 当两种类型相同时
  • 当这两种类型是同一类型的temped class 模板的实例化时

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

@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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM