可变长度模板参数列表?

发布于 2024-08-06 17:28:27 字数 204 浏览 10 评论 0原文

我记得看到过这样的事情:

template <ListOfTypenames>
class X : public ListOfTypenames {};

也就是说,X 继承了作为模板参数传递的类型名的可变长度列表。当然,这段代码是假设的。

不过,我找不到这方面的任何参考。是否可以?是C++0x吗?

I remember seing something like this being done:

template <ListOfTypenames>
class X : public ListOfTypenames {};

that is, X inherits from a variable length list of typenames passed as the template arguments. This code is hypothetical, of course.

I can't find any reference for this, though. Is it possible? Is it C++0x?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

木格 2024-08-13 17:28:27

你可以用当前的 C++ 来完成。您为模板提供了“足够多”的参数,并为它们提供了默认值:

class nothing1 {};
class nothing2 {};
class nothing3 {};

template <class T1 = nothing1, class T2 = nothing2, class T3 = nothing3>
class X : public T1, public T2, public T3 {};

或者您可以变得更复杂并使用递归。首先,前向声明模板:

class nothing {};

template <class T1 = nothing, class T2 = nothing, class T3 = nothing>
class X;

然后专门处理所有参数均为默认值的情况:

template <>
class X<nothing, nothing, nothing> {};

然后正确定义通用模板(之前仅前向声明):

template <class T1, class T2, class T3>
class X : public T1, public X<T2, T3>

注意如何在基类中继承 X但你错过了第一个参数。所以它们都沿着一个地方滑动。最终它们都将成为默认值,并且专业化将启动,它不会继承任何内容,从而终止递归。

更新:只是有一种奇怪的感觉,我之前发布过类似的内容,猜猜看……

You can do it in current C++. You give the template a "large enough" number of parameters, and you give them defaults:

class nothing1 {};
class nothing2 {};
class nothing3 {};

template <class T1 = nothing1, class T2 = nothing2, class T3 = nothing3>
class X : public T1, public T2, public T3 {};

Or you can get more sophisticated and use recursion. First you forward-declare the template:

class nothing {};

template <class T1 = nothing, class T2 = nothing, class T3 = nothing>
class X;

Then you specialise for the case where all the parameters are default:

template <>
class X<nothing, nothing, nothing> {};

Then you properly define the general template (which previously you've only forward-declared):

template <class T1, class T2, class T3>
class X : public T1, public X<T2, T3>

Notice how in the base class, you inherit X but you miss the first parameter. So they all slide along one place. Eventually they will all be defaults, and the specialization will kick in, which doesn't inherit anything, thus terminating the recursion.

Update: just had a strange feeling I'd posted something like this before, and guess what...

故事还在继续 2024-08-13 17:28:27

听起来您指的是 C++0x Variadic 模板。您还可以使用 Alexandrescu 的 TypeList 构造(来自 洛基

我相信所讨论的可变参数模板语法如下所示。

template <typename...T>
class X : public T... {};

Sounds like you are referring to C++0x Variadic Templates. You can also achieve the same effect using Alexandrescu's TypeList construct from Loki.

I believe the variadic template syntax in question would look like the following.

template <typename...T>
class X : public T... {};
与往事干杯 2024-08-13 17:28:27

正如其他人已经回答的那样,可变参数模板是下一个标准的一部分,但可以在当前的 C++ 中进行模拟。一种方便的工具是使用 Boost.MPL 库。在代码中,您编写一个模板参数(我们将其命名为“Typelist”),模板的用户将类型列表包装在 MPL 序列中。示例:

#include "YourType.h"
#include "FooBarAndBaz.h"
#include <boost/mpl/vector.hpp>

YourType<boost::mpl::vector<Foo, Bar, Baz> > FooBarBaz;

在“YourType”的实现中,您可以使用各种元函数访问Typelist中的元素。例如,at_c 是列表的第 N 元素。另一个例子,您问题中的“X”类可以用 inherit_linearly 编写为:

//Warning: Untested
namespace bmpl = boost::mpl;
template<class Typelist>
class X : bmpl::inherit_linearly<Typelist, bmpl::inherit<bmpl::_1, bmpl::_2> >::type
{
...
};

As others already answered, variadic templates are part of the next standard, but can be emulated in current C++. One convenient tool for this is to use the Boost.MPL library. In your code, you write a single template parameter (let's name it "Typelist"), and the users of your template wrap the typelist in an MPL sequence. Example:

#include "YourType.h"
#include "FooBarAndBaz.h"
#include <boost/mpl/vector.hpp>

YourType<boost::mpl::vector<Foo, Bar, Baz> > FooBarBaz;

In the implementation of "YourType", you can access the elements in Typelist with various metafunctions. For example, at_c<Typelist, N> is the Nth element of the list. As another example, the "X" class in your question could be written with inherit_linearly as:

//Warning: Untested
namespace bmpl = boost::mpl;
template<class Typelist>
class X : bmpl::inherit_linearly<Typelist, bmpl::inherit<bmpl::_1, bmpl::_2> >::type
{
...
};
月牙弯弯 2024-08-13 17:28:27

可变数量的模板是下一个 C++ 标准的一部分。但是,如果您使用 GCC(从版本 4.3 开始),您可以体验一下它。以下是GCC 中可用的 C++0x 功能列表。您正在寻找可变参数模板。

顺便说一句,如果您需要有关如何实现 Earwicker 所描述的继承机制的正式参考,可以在书上找到 C++ 模板

Variable number of templates is part of the next C++ standard. However, you can get a taste of it if you're using GCC (from version 4.3). Here's a list of available C++0x features in GCC. You're looking for Variadic Templates.

By the way, if you need a formal reference on how to achieve the inheritance mechanism as described by Earwicker, it's on the book C++ Templates.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文