如何编写无Dummy参数的模板参数计数递归基准用例?
问题描述
想要实现一个具备如下行为的模板函数:
// count_template_params<>() == 0 // count_template_params<int>() == 1 // count_template_params<int, int>() == 2 // count_template_params<int, int, int>() == 3 // etc...
目前实现的版本需要冗余的Dummy参数,移除该参数后,编译器会把递归基准情况误判为模板特化,询问是否存在无需Dummy参数的实现方式。当前实现代码如下:
#include <iostream> template<int DUMMY> constexpr int count_template_params() { return 0; } template<int DUMMY, class T, class... SS> constexpr int count_template_params() { return 1 + count_template_params<DUMMY, SS...>(); } int main(int argc, char **argv) { int count = count_template_params<0, int, int, int, int>(); std::cout << "Count=" << count << std::endl; }
实现方案
方案1:类模板+sizeof...运算符(C++11及以上)
直接利用标准库的sizeof...运算符获取变参包的大小,通过类模板包装后提供函数接口:
#include <iostream> template<typename... Ts> struct count_params { static constexpr int value = sizeof...(Ts); }; template<typename... Ts> constexpr int count_template_params() { return count_params<Ts...>::value; } int main() { std::cout << count_template_params<>() << std::endl; // 输出0 std::cout << count_template_params<int>() << std::endl; // 输出1 std::cout << count_template_params<int, int>() << std::endl;// 输出2 }
方案2:函数重载替代模板特化(C++11及以上)
把基准情况写成普通函数而非模板函数,通过重载机制避免特化判定问题:
#include <iostream> // 基准情况:无模板参数时调用普通函数 constexpr int count_template_params() { return 0; } // 递归情况:匹配至少一个模板参数的版本 template<typename T, typename... Ts> constexpr int count_template_params() { return 1 + count_template_params<Ts...>(); } int main() { std::cout << count_template_params() << std::endl; // 输出0 std::cout << count_template_params<int>() << std::endl; // 输出1 std::cout << count_template_params<int, int, int>() << std::endl;// 输出3 }
方案3:C++17折叠表达式(最简洁)
利用C++17的折叠表达式一行实现,无需递归:
#include <iostream> template<typename... Ts> constexpr int count_template_params() { return (0 + ... + 1); } int main() { std::cout << count_template_params<>() << std::endl; // 输出0 std::cout << count_template_params<int>() << std::endl; // 输出1 std::cout << count_template_params<int, double, char>() << std::endl;// 输出3 }
内容的提问来源于Stack Exchange,提问作者jyelon
相关产品推荐
相关产品推荐

