功能模板与Variadic模板过载:Intel C 编译器版本18产生的结果不同于其他编译器.英特尔是错误的



考虑以下代码段:

template<typename T, template<typename, typename ...> class A, typename ... Ts>
int a(A<T, Ts...> arg){
  return 1; // Overload #1
}
template<typename A>
int a(A arg) {
  return 2;  // Overload #2
}
template<typename T>
struct S{};
int main() {
  return a(S<int>());
}

通过模板类实例调用函数a时,我希望编译器能选择更特殊的功能超载#1。根据编译器资源管理器的说法,Clang,GCC和Intel升至版本17实际上确实选择了Overload#1。相比之下,后来的英特尔编译器版本(18和19(选择Overload#2。

代码定义不明,还是最新的英特尔编译器版本错误?

以下未能在ICC 19.01上致电a()

template<template<typename, typename ...> class A, typename T, typename ... Ts>
int a(A<T, Ts...> arg){
    return 1;
}
template<typename T>
struct S{};
int foo()
{
    return a(S<int>());
}

根本无法将a()视为候选人,这就是问题在问题中有所不同的原因。

C 17草稿说:

(其中p是模板 - 网板参数,a是实例化参数(

17.3.3 模板模板参数

  1. 模板 - 题词与模板模板参数p匹配,当p至少与 template-argumentA。如果P包含一个参数包,则A还匹配P,如果A的每个模板参数 匹配第
  2. 的模板头中的相应模板参数

到目前为止很好,<int参数头与参数头 <T匹配。

两个模板参数匹配 如果它们是相同的(类型,非类型,模板(,对于非类型模板 - 参数,则它们的类型是 等效(17.6.6.1(,和对于模板模板 - 参数,每个相应的模板参数 递归匹配。

看起来不错,intT匹配。

当P的模板头包含模板参数包(17.6.3(时 参数包将匹配零或更多模板参数或模板参数包中的模板头组件包 与p中的模板参数包相同类型和形式的A(忽略这些模板是否 参数是模板参数包(。

这很难解析,但是对我来说似乎还可以。据我了解,编译器应该将参数与模板网板参数匹配。它明确地谈论了零或更多,我们在这里零。

最新更新