Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 函数重载:空参数列表与参数包_C++_Templates_Language Lawyer_Variadic Templates_Overload Resolution - Fatal编程技术网

C++ 函数重载:空参数列表与参数包

C++ 函数重载:空参数列表与参数包,c++,templates,language-lawyer,variadic-templates,overload-resolution,C++,Templates,Language Lawyer,Variadic Templates,Overload Resolution,GCC、Clang和MSVC都使用#1 然而,标准中的偏序规则规定: 如果与Pi相对应的参数声明是函数参数包,则其声明器id的类型将与a的参数类型列表中的每个剩余参数类型进行比较。每次比较都会推断由函数参数包展开的模板参数包中后续位置的模板参数。在偏序期间,如果Ai最初是一个函数参数包: (10.1)如果p不包含与Ai对应的函数参数类型,则忽略Ai (10.2)否则,如果Pi不是函数参数包,则模板参数推断失败。 当我们从#2推导出#1时,T,Args…作为A,T作为p,p不包含对应于Args

GCC、Clang和MSVC都使用#1

然而,标准中的偏序规则规定:

如果与Pi相对应的参数声明是函数参数包,则其声明器id的类型将与a的参数类型列表中的每个剩余参数类型进行比较。每次比较都会推断由函数参数包展开的模板参数包中后续位置的模板参数。在偏序期间,如果Ai最初是一个函数参数包:

  • (10.1)如果p不包含与Ai对应的函数参数类型,则忽略Ai

  • (10.2)否则,如果Pi不是函数参数包,则模板参数推断失败。

当我们从#2推导出#1时,
T,Args…
作为A,
T
作为p,p不包含对应于
Args…
的模板参数<代码>参数…被忽略,因此可以成功地从#2推导出#1

然后从#1中推断#2,将
T
作为A,将
T,Args…
作为p,也成功地得到
T=T,Args…={}


因此,根据偏序规则,当调用
call(10)
时,编译器应该给出不明确的错误,但实际上所有编译器都调用了#1,这是为什么?

编译器是正确的<代码>#1比
#2
更专业


偏序模板参数包的规则在中指定:

使用结果类型
p
A
,然后按如下方式进行扣除 在[温度扣除类型]中描述。如果
P
是一个功能参数包, 参数模板的每个剩余参数类型的类型
A
与函数的声明器id的类型
P
进行比较 参数包。每次比较都会推断出 模板参数包中的后续位置由 函数参数包。类似地,如果
A
是从 函数参数包,它与每个剩余参数进行比较 参数模板的类型。如果对给定的 类型,则参数模板中的类型被视为至少 与参数模板中的类型一样专用

当参数模板为
#1
且参数模板为
#2
时,将
#2
中的声明符id
Args
(这是一种类型)与
#1
中的每个剩余参数进行比较(没有)。因此,
#2
至少与
#1
一样专业化

当参数模板为
#2
且参数模板为
#1
时,将
#2
中的声明符id
Args
(这是一种类型)与
#1
中的每个剩余参数进行比较(没有)。因此,
#1
至少与
#2
一样专业化

看起来模棱两可,对吧?现在我们有了打破僵局的人:

如果在考虑上述因素后,函数模板
F
至少为 专用于函数模板
G
,反之亦然,如果
G
具有
F
没有对应的尾部参数包 参数,并且如果
F
没有后续参数包,则
F
G
更专业


显然,
#1
#2

更专业化,你必须在文本中用单引号转义
,否则它不可见,这对你来说是固定的,但不确定我是否遗漏了一些不是专业化的东西?@奇怪的是不是。这是一个主要的模板。
template <typename T>
void call(T) {  //#1
    std::cout << "1" << std::endl;
}

template <typename T, typename...Args>
void call(T, Args...) {  //#2
    std::cout << "2" << std::endl;
}
call(10);