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

如何使用默认参数和更多参数选择模板特殊化

谢鸿
2023-03-14

https://stackoverflow.com/a/22487113/4416169在下面的答案中,我们可以看到详细的代码:

#include <iostream>
#include <type_traits>

template <typename T, T N, typename = void > 
struct X {
  static const bool isZero = false;
};

template <typename T, T N>
struct X < T, N, typename std::enable_if<N == 0>::type > {
  static const bool isZero = true;
};

int main(int argc, char* argv[]) {
    std::cout << X <int, 0>::isZero << std::endl;
    std::cout << X <int, 1>::isZero << std::endl;
    return 0;
}

https://stackoverflow.com/a/35652391/4416169在这里,我们可以看到如何选择模板:

选择模板专门化分为五个步骤:

  1. 以主模板声明为例

首先,我知道SFINAE将负责使用std::enable\u if排除结构

  1. 模板

我们现在知道,当我们试图访问X

>

  • 编译器是否总是喜欢参数最少的模板(在所有可用的模板专门化中)?

    此外,扩展:这是否意味着具有最少实际参数的模板被选择为具有相同数量的显式(显式和非默认或强制性)参数,但其余参数设置为默认值的模板?

    更清楚地说:

    template<typename T, T N, typename C = void>
    struct defTempArgStruct {
        static constexpr unsigned int value = 0;
    };
    
    template<typename T, T N>
    struct  defTempArgStruct<T,N>
    {
        static constexpr unsigned int value = 99;
    };
    
    
    int main()
    {
        std::cout << defTempArgStruct<int, 2>::value << std::endl;
    }
    

    为什么代码选择第二个专用模板(

    template<typename T, T N>
    struct  defTempArgStruct<T,N,float>
    {
        static constexpr unsigned int value = 99;
    };
    

    非常混乱。

    如果我有任何地方出错,请立即纠正

  • 共有1个答案

    隆礼骞
    2023-03-14

    可行的部分专门化始终优于主模板:

    [temp.class.spec.match]/1当在需要实例化类的上下文中使用类模板时,需要确定实例化是使用主模板还是部分专门化之一生成。这是通过将类模板特殊化的模板参数与部分特殊化的模板参数列表匹配来实现的。

    (1.1)-如果恰好找到一个匹配的专门化,则从该专门化生成实例化
    (1.2)-如果找到多个匹配专门化,则使用偏序规则(17.5.5.2)确定其中一个专门化是否比其他专门化更专业化。如果没有一个专门化比所有其他匹配的专门化更专门化,那么类模板的使用是不明确的,并且程序的格式是错误的
    (1.3)-如果未找到匹配项,则从主模板生成实例化。

     类似资料:
    • 如果允许我执行以下操作: 为什么我主要不被允许做以下事情? 但我必须具体说明以下几点: C11引入了默认的模板参数,现在我完全无法理解它们。

    • 已编辑(原始问题只有int A,int B): 模板参数推断在两个专门化之间比较的#参数相同时按预期工作,但在它们不同时失败(因为在其中一个专门化中包含默认参数)。 例如:为什么模板参数推导在一种情况下与另一种情况下失败,有人能指出解释这一点的任何资源/标准吗? 错误:模糊模板实例化'类Foo

    • 标准中似乎没有规则提到模板参数需要默认参数的情况。 在dcl中。fct。默认值#1 如果在参数声明中指定了初始化子句,则将此初始化子句用作默认参数。缺省参数将用于缺少尾随参数的调用。 在本节中,规则明确描述了何时为函数调用提供默认参数。但是,我在标准中没有找到与上面描述何时提供默认参数作为模板参数的语句类似的引用。 例如

    • 根据enable_if结构的定义: 我想知道怎么做 特别是: 在

    • 下面的代码是合法的C(用g-Wall编译干净): 但是,当我尝试使用nvcc编译此文件时,会出现以下错误: nvcc t.cu t.cu(39):警告:当重新声明未引用的函数模板时,指定默认参数是不标准的 t、 cu(39):警告:重新定义默认参数 t.cu(51):警告:重新声明未引用的函数模板时指定默认参数是不标准的 t、 cu(51):警告:重新定义默认参数 t、 cu(53):错误:模板实

    • 是否允许在友元声明中为模板参数提供默认值? Visual Studio 2015似乎允许这样做。gcc拒绝了。我在cppreference页面上找不到任何内容。