Ant*_*ole 2 c++ variadic-templates
我正在尝试编写一个函数,如果在运行时传递的参数包含在编译时设置的整数列表中,则该函数的计算结果为 true。我尝试在这里调整打印示例:https://www.geeksforgeeks.org/variadic-function-templates-c/# :~:text=Variadic%20templates%20are%20class%20or,help%20to%20overcome%20this% 20期.
并尝试过这个:
bool Contains(int j) { return false; }
template<int i, int... is>
bool Contains(int j) { return i == j || Contains<is...>(j); }
Run Code Online (Sandbox Code Playgroud)
但是,它给了我一个编译器错误,指出“'包含':找不到匹配的重载函数”。
我尝试过摆弄尖括号,但似乎无法让它工作。
你的问题是递归调用是
Contains<is...>(j)
Run Code Online (Sandbox Code Playgroud)
这会查找的模板重载Contains。
您的基本情况:
bool Contains(int j) { return false; }
Run Code Online (Sandbox Code Playgroud)
不是模板。因此,当包为空时,最后的调用为:
Contains<>(j)
Run Code Online (Sandbox Code Playgroud)
找不到非模板。
有一些简单的修复方法。
最好的版本需要C++版本大于c++11;17 我认为:
template<int... is>
bool Contains(int j) { return ((is == j) || ...); }
Run Code Online (Sandbox Code Playgroud)
这篇文章简短、简单、清晰。
简单的 pre- c++14生成 O(n^2) 总符号长度,而无需跳过大量的循环。c ++17 的符号总长度为 O(n),要好得多。c ++14是钝角的,但总符号长度也是 O(n) 。
因此,这里有一些适合适度长度的包的c++11代码:
c++11都不支持空包:
template<class=void>
bool Contains(int j) { return false; }
template<int i, int... is>
bool Contains(int j) { return i == j || Contains<is...>(j); }
Run Code Online (Sandbox Code Playgroud)
它依赖于这样一个事实:除了空包之外,第一个重载永远不会被选择。(由于标准中的一个怪癖,对包装是否为空进行任何检查都是非法的)。
另一种不支持空包的方式是:
template<int i>
bool Contains(int j) { return i==j; }
template<int i0, int i1, int... is>
bool Contains(int j) { return Contains<i0>(j) || Contains<i1, is...>(j); }
Run Code Online (Sandbox Code Playgroud)
这比第一个更明确。
使总符号长度低于 O(n^2) 的技术涉及对整数参数包进行二叉树重新打包。这是棘手且令人困惑的,我建议不要这样做。
最后,这是c++14中的一个 hacky ,它避免了 O(n^2) 符号长度问题:
template<int...is>
bool Contains(int j) {
using discard=int[];
bool result = false;
(void)discard{0,((void)(result = result || (is==j)),0)...};
return result;
}
Run Code Online (Sandbox Code Playgroud)
不要问它是如何工作的。这是c++17故意废弃的技术。
| 归档时间: |
|
| 查看次数: |
386 次 |
| 最近记录: |