C++

参数包实现简单元组

之前虽然稍微了解过,不过不太会,尤其是别人写的元组的代码(虽然和标准库写的实在是差远了),一直看的云里雾里的。今天突然回想起来这件事,于是又重新看了看。

不妨就以元组为例,稍稍地进一步理解一下参数包。

template<typename... _Args> class Tuple {};

template<> class Tuple<> {};

template<typename _Value, typename... _Args>
class Tuple<_Value, _Args...>: public Tuple<_Args...> {
private:
    _Value _Val;
public:
    Tuple() {}
    Tuple(_Value _Val, _Args... _Arg_pack)
        : _Val(_Val), Tuple<_Args...>(_Arg_pack...) {}
    _Value value() { return _Val; }
    Tuple<_Args...> next() { return *this; }
};

我们声明了三种 Tuple:模板为单一参数包的形式1,模板无参的形式2 和 模板为一个参数、一个参数包的形式3。形式1 和 形式3 是我们在继承体系中所使用的桥梁。

我们在构造 Tuple<_Val, _Args…> 时,做了这样的事:把 Tuple 的 _Val 成员用模板的第一个参数初始化,然后用剩下的参数包初始化其父类 Tuple<_Args…>

可以想见,当我们的初始化继续递归下去,总有一步会出现这样的情况:_Args… 只存在一个数据成员,那么 _Val 会获得这个唯一的数据成员,而 Tuple<_Args…> Constructor 得不到任何参数填充,我们会调用无参的 Tuple Constructor 为其初始化,使其被初始化成 Tuple<> 类型的对象。

当 next 被调用,我们return *this,由于返回值设置的原因,会隐式地把子类的 Tuple<_Val, _Args…> 给 cast 成父类的 Tuple<_Args…>,于是我们便得到了元组的下一个元素。

这个例子把 C++ 的继承和参数包结合了起来,还是非常不错的。

A little learning is a dangerous thing.

订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请发表评论。x
()
x