子类化STL容器:范围构造器不起作用

时间:2018-06-21 09:15:02

标签: c++ templates stl allocator

许多STL容器都有一个范围构造函数,可用于初始化容器元素:

char ary[] = {'a', 'b', 'c'};
vector<char> v(ary, ary + 3);

我将特定的STL容器子类化,仅出于默认情况下使用自定义分配器的目的:

template<class _Ty, class _Ax = stl_allocator<_Ty> >
class xvector
    : public std::vector<_Ty, _Ax>
{
};

这很好用,但是我不能再使用范围构造器了:

xvector<char> v2(ary, ary + 3);

产生以下错误:

error C2661: 'xvector<_Ty>::xvector' : no overloaded function takes 2 arguments
    with
    [
        _Ty=char
    ]

但是,我可以使用assign方法:

xvector<char> v3;
v3.assign(ary, ary + 3);

有人可以解释为什么在分配方法起作用时,范围构造器不起作用吗?我使用的是VC ++ 2008,从此我可以知道范围构造函数的参数列表和Assign方法完全相同。

更新 谢谢您的回答,但对我而言,关键是我忘记了构造器不是继承的,因此只有默认构造器可用(与范围构造器无关)。

我还应该提到我被迫坚持使用VS2008 / C ++ 03,因为目标平台不支持最新的编译器。

2 个答案:

答案 0 :(得分:5)

  

我正在使用VC ++ 2008

这意味着您可能无法访问C ++ 11。构造函数不会被继承,在C ++ 11之前,甚至没有办法指定应该被继承。在C ++ 03中,据我所知,有两个选择:

  1. 重新定义std::vector的所有构造函数,并将它们转发给基类c'tor。这很脆弱,并且可能在升级您的工具链时不能很好地发挥作用。我之所以这样说是因为std::vector的构造函数的定义在C ++ 03和C ++ 11之间已更改。您需要诉诸一些不愉快才能使其正常工作。

  2. 使用别名代替继承:

    template<class Ty, class Ax = stl_allocator<Ty> >
    struct xvector
    {
        typedef std::vector<Ty, Ax> type;
    };
    

    您不能再直接使用xvector<...>,而必须使用xvector<...>::type,但是通过这种方式获得的类型std::vector 。而且它对工具链的升级更加友好。

答案 1 :(得分:1)

从stl容器继承是一个坏主意,如here

所述

但如果您的目标是

  

默认使用自定义分配器

您可以使用c ++ 11

template<class _Ty, class _Ax = stl_allocator<_Ty> >
using xvector = std::vector<_Ty, _Ax>;