当前位置: 首页 > 知识库问答 >
问题:

为什么匹配模板类上的部分类模板专门化与没有模板匹配的另一个部分专门化不明确?

郑旭
2023-03-14

这个问题可能太难在标题中的on句子中描述,但这里有一个最小的例子:

#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;    
}
  • 当两种类型相同时
  • 当这两种类型是同一类型的temped类模板的实例化时

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

共有1个答案

钱展
2023-03-14

@超级现在被删除的答案基本上是对的。std::enable_if_t<...>在偏序中不是void;作为依赖类型,它原则上可以是完全任意的。对于偏序的目的,它有效地被认为是一个完全唯一的类型。

由于这种不匹配,偏序期间的推导在两个方向上都失败,并且专门化是不明确的。

 类似资料:
  • 还尝试在专门化的中进行模板方法专门化: 这一次它编译,但调用原始方法,即 解决方案

  • 但是指定它是,因此它不再是模板类。它是否可以像虚函数一样专门化或重写?

  • 我有几个模板参数的模板结构 此结构适用于所有模板,但结果无效的情况除外。我知道,不能实现为void类型,所以我当前的解决方案是使用如下的部分专门化: 这允许执行以下操作: 有没有一种方法可以使编译而不会在C 14标准中进行部分类特化?我可以使用和类型trait组合,但我想找到是否有一种方法: > 模板类方法的特殊化部分显式 模板类方法的实例化

  • 让我们考虑以下代码: 我知道第二个声明是重载,而不是部分专业化: 但我想知道它与部分专业化有何不同?它为我们提供了与部分专业化相同的功能,不是吗?

  • 请向我解释选择模板专用化的规则。我举一个例子: 为什么输出为?一般来说,专用类中的默认模板参数会发生什么情况?它会带来一些影响吗?