Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

New vector class with range checking

33 views
Skip to first unread message

Doug Mika

unread,
Jun 8, 2015, 1:49:15 PM6/8/15
to
I found the following improvement of our vector class in my book. It performs range checking when accessing vector. The thing that confuses me about this short little improvement is the line:
using vector<T>::vector;

How is it that this line lets our Vec class all of the sudden come with Vec constructors inherited from vector when Vec and vector have entirely different names? Perhaps I should ask, what exactly the line means?

Here's the short program:

template<typename T> class Vec : public std::vector<T> {
public:
using vector<T>::vector;

T& operator[](int i) //range check
{ return vector<T>::at(i); }
const T& operator[](int i) const
{ return vector<T>::at(i); }
};
Message has been deleted

Richard

unread,
Jun 8, 2015, 2:10:50 PM6/8/15
to
[Please do not mail me a copy of your followup]

Doug Mika <doug...@gmail.com> spake the secret code
<d10e9a51-e713-4eea...@googlegroups.com> thusly:

>I found the following improvement of our vector class in my book.

It's not an improvement. std::vector<> already has range-checked
access through the use of the at() member function.

All this is doing is making operator[] a synonym for at(), forcing all
accesses to be range-checked.

This is actually a step backwards.

C++'s std::vector<> has a non-range checked accessor and a
range-checked accessor because C++ follows the philosophy of "don't pay
for what you don't use". If you don't need range-checked accessing,
then you shouldn't have to pay the cost of range checking every access
and you use operator[]. If you want range-checked accessing, then you
can decide to pay the cost and use at().

Making operator[] do range-checking is simply going to confuse *any*
reader of your code because they are culturally trained that
at is for range checking and operator[] is for unchecked access.

>template<typename T> class Vec : public std::vector<T> {
>public:
> using vector<T>::vector;

This is a "using declaration"
<http://en.cppreference.com/w/cpp/language/using_declaration>
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Victor Bazarov

unread,
Jun 8, 2015, 2:16:03 PM6/8/15
to
A constructor is a function whose name [for the purposes of syntax]
coincides with the name of the class. In a class template, the name of
a c-tor coincides with the name of the template (IOW, you don't need the
template args for the syntax). So, "vector<T>::vector" is the name of
all constructors of the class vector<T>. Declaring c-tors in the
'using' declaration like you did *inherits* the constructors in C++11
(see [class.inhctor] section).

Now you know.

V
--
I do not respond to top-posted replies, please don't ask
Message has been deleted

Mr Flibble

unread,
Jun 8, 2015, 2:34:53 PM6/8/15
to
This is a really brain dead idea. People who rely on at() to check their
code is correct need shooting. Forcing people to do the same just isn't
cricket.

And another thing the correct type to use for indexing a std::vector<T>
is std::vector<T>::size_type not 'int'.

/Flibble


Doug Mika

unread,
Jun 8, 2015, 3:09:00 PM6/8/15
to
But the question remains, we inherit constructors from vector<T>, hence constructors with the name vector<T>::vector, BUT our class has the name Vec, and hence all of our Vec constructors should have name Vec NOT vector. Does the using vector<T>::vector; rename my vector constructors to Vec?

Victor Bazarov

unread,
Jun 8, 2015, 3:43:28 PM6/8/15
to
> But the question remains, we inherit constructors from vector<T>,
> hence constructors with the name vector<T>::vector, BUT our class has
> the name Vec, and hence all of our Vec constructors should have name
> Vec NOT vector. Does the using vector<T>::vector; rename my vector
> constructors to Vec?

Constructors don't have names. Inheriting of constuctors basically
duplicates the constructors with certain arguments in the derived class
and makes sure that the corresponding base class' constructor is called
(of course you need to take care of initializing your own data members
in such case).

What book in C++11 are you reading that doesn't explain this?

Doug Mika

unread,
Jun 8, 2015, 3:55:46 PM6/8/15
to
So in my Vec class, if I write
Vec<int> myVector;
this will call:
vector<int> myVector?

and if I write:
Vec<string> myVector(3,"default");
this will call
vector<string> myVector(3, "default");

and if my Vec class has an extra member that requires initialization upon the creation of a Vec instance, then I should re-write all vector<T>::vector constructors in Vec and call these explicitly from my defined Vec<T> constructors?

Victor Bazarov

unread,
Jun 9, 2015, 9:24:54 AM6/9/15
to
On 6/8/2015 3:55 PM, Doug Mika wrote:
> So in my Vec class, if I write
> Vec<int> myVector;
> this will call:
> vector<int> myVector?

Yes, *as part of constructing* your Vec<int>.

>
> and if I write:
> Vec<string> myVector(3,"default");
> this will call
> vector<string> myVector(3, "default");

Most likely.

> and if my Vec class has an extra member that requires initialization
> upon the creation of a Vec instance, then I should re-write all
> vector<T>::vector constructors in Vec and call these explicitly from
> my defined Vec<T> constructors?

Yes. Inheriting constructors is only useful if your data members
require only default-initialization or your class has no additional members.
0 new messages