0

Many STL containers have a range constructor that you can use to initialize the container elements:

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

I subclass specific STL containers, solely for the purpose of using a custom allocator by default:

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

This works well, but I can't use the range constructor anymore:

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

Generates the following error:

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

However, I can use the assign method:

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

Can someone explain why the range-constructor doesn't work while the assign method does? I'm using VC++ 2008 and from what I can tell the argument list of the range constructor and the assign method is exactly the same.

Update Thank you for your answers, but for me the key-point is that I forgot that constructurs aren't inherited and so only the default constructor is available (it doesn't have anything to do with range-constructors).

I also should have mentioned that I'm forced to stick to VS2008 / C++ 03 because the target platform doesn't support more recent compilers, unfortunately.

Krid
  • 95
  • 1
  • 11

2 Answers2

5

I'm using VC++ 2008

Which means you probably don't have access to C++11. Constructors aren't inherited, and prior to C++11 there was no way to even specify a c'tor should be inherited. In C++03 you have as far as I can tell two options:

  1. Redefine all of std::vector's constructors, and have them forward to the base class c'tor. That's brittle, and likely won't play well with upgrading your tool-chain. I say that because the definition of std::vector's constructors have changed between C++03 and C++11. You'd need to resort to some unpleasantness to make it work.

  2. Use aliasing instead of inheritance:

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

    You can't use xvector<...> directly anymore, instead having to use xvector<...>::type, but the type you get this way is a std::vector. And it's more toolchain-upgrade-friendly.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
1

inheriting from stl containers is a bad idea as explained here

but if you objective is

using a custom allocator by default

with c++11 you can do

template<class _Ty, class _Ax = stl_allocator<_Ty> >
using xvector = std::vector<_Ty, _Ax>;
Tyker
  • 2,971
  • 9
  • 21