在调用时仅指定一些模板参数
Specifying only some template parameters at call time
考虑一小段可变参数模板代码:
#include <type_traits>
template<int Dim, class... Idcs>
std::enable_if_t<sizeof...(Idcs) == 1> doit(Idcs... idcs)
{}
int main()
{
doit<0>(1);
}
当我使用 GCC/Clang 编译它时,编译得很好,Idcs
被推导出为(int)
。
但是,当我尝试使用英特尔的编译器(版本 18.0.0,20170811)编译它时,出于某种原因,它认为我手动将Idcs
指定为空参数包,然后enable_if_t
失败。
来自 icc 的编译器错误:
myfile.cpp(9): error: no instance of function template "doit" matches the argument list
argument types are: (int)
doit<0>(1);
^
myfile.cpp(4): note: this candidate was rejected because there is a type mismatch after argument substitution
std::enable_if_t<sizeof...(Idcs) == 1> doit(Idcs... idcs)
^
compilation aborted for myfile.cpp (code 2)
可以通过更改main()
内部的调用以完全指定所有模板参数来解决此问题
doit<0, int>(1);
但是,我想了解为什么原始代码在所有 14 个编译器上没有给出相同的结果C++。这是期望成功/失败编译的东西,还是某种未定义的行为,为什么?
作为参考,这些是我用来编译的命令(在 Linux 上,各种版本/风格):
g++ -std=c++14 myfile.cpp
clang++ -std=c++14 myfile.cpp
icc -std=c++14 myfile.cpp
这很可能是 icc 中的一个错误,在 v19 中修复了:https://godbolt.org/z/k1vbY9
更多的研究表明,icc v18(不编译你的代码)在没有enable_if
的情况下正确推断Idcs
https://godbolt.org/z/WCZ_w8:
template<size_t Dim, class... Idcs>
size_t doit(Idcs... idcs)
{
static_assert(sizeof...(Idcs) == 1);
return sizeof... (Idcs);
}
auto test()
{
return doit<0>(1); // correctly returns 1 even on icc v18
}
相关文章:
- 当对话框被接受时,如何用参数调用槽
- 使用用户定义的参数调用future/async并调用类方法
- 我使用向量来创建类对象列表.初始化向量时如何使用参数调用构造函数?
- 将成员函数作为构造函数参数调用时出错 "Variable is not a type name"
- 不允许运算符 const 参数调用 const 成员函数
- 为变量模板的每个参数调用模板函数
- 如何在窗口中使用注入的 dll 中的参数调用函数
- 按引用调用与按指针参数调用的差异 前递增和后递增
- 为什么使用不匹配的参数调用重载函数仍然有效
- PowerShell 使用结构类型参数调用 C++ DLL 的导出函数
- 基于枚举参数调用专用模板方法
- C++ 如何根据作为输入传递的参数调用一个构造函数或另一个构造函数?
- 如何使用类模板参数来更改参数调用和函数签名?
- lambda 函数使用其参数作为模板参数调用模板函数
- Android:使用 c++ 中的 byte[] 参数调用 java 方法
- 使用不同的模板参数调用模板类的对象
- C++编译时检查是否可以用某种类型的参数调用重载函数
- 是否可以基于类模板的参数调用类方法和全局方法
- 使用单独的参数调用"boost::process::system()"时,获取"execv
- C++大括号初始值设定项作为参数调用不同的构造函数,然后预期