用于打印参数包内容的递归可变参数模板
如何创建递归可变参数模板来打印参数包的内容? 我正在尝试这样做,但它无法编译:
template <typename First, typename ...Args>
std::string type_name () {
return std::string(typeid(First).name()) + " " + type_name<Args...>();
}
std::string type_name () {
return "";
}
我该如何结束递归?
How is it possible to create a recursive variadic template to print out the contents of a paramater pack?
I am trying with this, but it fails to compile:
template <typename First, typename ...Args>
std::string type_name () {
return std::string(typeid(First).name()) + " " + type_name<Args...>();
}
std::string type_name () {
return "";
}
How shall I end the recursion?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
实际上有一种非常优雅的方式来结束递归:
我最初尝试了
template
和template
但那是被认为是不明确的(其余可以是零元素)。然后这个问题向我展示了最终的解决方案: Compilation Error on Recursive Variadic Template Function注意,为了避免一些代码重复,您还可以这样做:
There's actually a very elegant way to end the recursion:
I initially tried
template <typename Last>
andtemplate <typename First, typename ...Rest>
but that was considered ambiguous (Rest can be zero elements). This question then showed me the definitive solution: Compilation Error on Recursive Variadic Template FunctionNote, to avoid a bit of code duplication, you could also do:
您需要使用部分特化来结束递归,但由于您无法部分特化 C++ 中的自由函数,因此您需要创建一个带有静态成员函数的实现类。
Impl
的第一个声明只是 g++ 4.6(及更低版本)中的缺陷的解决方法。一旦正确实现了可变参数模板,就没有必要了。在 ideone.com 上查看实际情况
You need to use partial specialisation to end the recursion, but since you can't partially specialise free functions in C++, you need to create an implementation class with a static member function.
That first declaration of
Impl
is just a workaround for a shortcoming in g++ 4.6 (and below). It won't be necessary once it implements variadic templates correctly.Check it out in action at ideone.com
C++17 的
if constexpr
允许您在一个模板声明中执行此操作,与许多旧的解决方案不同,它非常容易理解:C++17's
if constexpr
allows you to do this in one template declaration which is, unlike a lot of the older solutions, pretty easy to understand:作为不存在的函数部分特化的替代方法,您可以在类型化器类上使用重载:
As an alternative to non-existing partial specialization for functions, you can use overloading on a typifier class:
作为替代方案,您可以就地解压参数包,如下例所示:
实际上不需要递归来执行此操作。
As an alternative, you can unpack the parameter pack in-place as in the following example:
Recursion is not required actually to do that.
使用C++17折叠表达式:
Use C++17 fold expression: