use*_*653 10 c++ templates language-lawyer variadic-templates
考虑以下代码片段:
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>());
}
Run Code Online (Sandbox Code Playgroud)
在a使用模板类的实例调用函数时,我希望编译器选择更特殊的函数重载#1。根据编译器资源管理器的说法,直到版本17的clang,gcc和intel确实选择了#1重载。相反,后来的intel编译器版本(18和19)选择#2重载。
代码定义不正确吗?还是最新的intel编译器版本错误?
以下内容无法在 icc 19.01 上调用:a()
template<template<typename, typename ...> class A, typename T, typename ... Ts>\nint a(A<T, Ts...> arg){\n return 1;\n}\n\ntemplate<typename T>\nstruct S{};\n\nint foo()\n{\n return a(S<int>());\n}\nRun Code Online (Sandbox Code Playgroud)\n\n它根本无法将其视为a()候选者,这就是问题中的重载不同的原因。
C++17 草案说:
\n\n(其中 P 是模板-模板参数,A 是实例化参数)
\n\n\n\n\n17.3.3模板模板参数
\n\n\n
\n- 当 P 至少与模板参数 A 一样专用时,模板参数与模板参数 P 匹配。如果 P 包含参数包,则 A 也与 P 匹配,前提是每个 A\xe2\x80\x99s 模板parameters\n 匹配 P 的 template-head 中对应的模板参数。
\n
到目前为止一切顺利,<int参数 head 与参数 head 匹配<T。
\n\n\n如果两个模板参数属于同一类型(类型、非类型、模板),则它们匹配\n;对于非类型模板参数,它们的类型\n 是等效的 (17.6.6.1);对于模板模板参数,\n它们各自对应的模板参数\n 递归地匹配。
\n
看起来还是不错的,int也T很搭配。
\n\n\n当 P\xe2\x80\x99s template-head 包含模板参数包 (17.6.3) 时,模板参数包将与 A 的 template-head\n 中的零个或多个模板参数或模板参数包匹配与P中模板参数包的类型和形式相同(忽略这些模板参数是否是模板参数包)。
\n
这更难解析,但对我来说似乎还可以。据我了解,编译器应该将参数与模板模板参数相匹配。它明确地谈论零或更多,而我们这里有零。
\n| 归档时间: |
|
| 查看次数: |
141 次 |
| 最近记录: |