inheritance and typedef - compilation error

S

subramanian100in

Suppose the following program is named x.cpp

#include <iostream>
#include <vector>

using namespace std;

template <class T>
class Vec : public vector<T>
{
public:
vector<T>::iterator begin()
{
cout << "non-const begin() is called" << endl;
return vector<T>->begin();
}

vector<T>::const_iterator begin() const
{
cout << "const begin() is called" << endl;
return vector<T>->begin();
}
};

int main()
{
return 0;
}

When I compile this program with g++ as
g++ -std=c++98 -pedantic -Wall -Wextra x.cpp

I am getting the following compilation errors:

x.cpp:10: error: expected `;' before "begin"
x.cpp:16: error: expected `;' before "vector"
x.cpp:16: error: expected `;' before "begin"
x.cpp:21: error: expected `;' before '}' token

Please help me fix the compilation errors.

Can't we use the base-class iterator and const_iterator types in the
derived class Vec ?

Kindly explain.

Thanks
V.Subramanian
 
G

Guest

Suppose the following program is named x.cpp

#include <iostream>
#include <vector>

using namespace std;

template <class T>
class Vec : public vector<T>

std::vetor<T> does not have a virtual destructor and is not designed to
be used as a base class. The usual recommendation is to either use
private inheritance or have a vector as a member instead.
{
public:
vector<T>::iterator begin()

typename vector<T>::iterator begin()

iterator is a dependent type and you need to tell the compiler that it
is a type and nothing else.
{
cout << "non-const begin() is called" << endl;
return vector<T>->begin();

return vector<T>::begin();

The -> operator is used when you have a pointer, you have no such thing
in this case.
 
A

anon

Suppose the following program is named x.cpp

#include <iostream>
#include <vector>

using namespace std;

template <class T>
class Vec : public vector<T>
{
public:
vector<T>::iterator begin()
{
cout << "non-const begin() is called" << endl;
return vector<T>->begin();
}

vector<T>::const_iterator begin() const
{
cout << "const begin() is called" << endl;
return vector<T>->begin();
}
};

int main()
{
return 0;
}

When I compile this program with g++ as
g++ -std=c++98 -pedantic -Wall -Wextra x.cpp

I am getting the following compilation errors:

x.cpp:10: error: expected `;' before "begin"
x.cpp:16: error: expected `;' before "vector"
x.cpp:16: error: expected `;' before "begin"
x.cpp:21: error: expected `;' before '}' token

Please help me fix the compilation errors.

#include <iostream>
#include <vector>

using namespace std;

template <class T>
class Vec : public vector<T>
{
public:
typename vector<T>::iterator begin()
{
cout << "non-const begin() is called" << endl;
return vec.begin();
}

typename vector<T>::const_iterator begin() const
{
cout << "const begin() is called" << endl;
return vec.begin();
}
private:
vector<T> vec;
};

int main()
{
return 0;
}
 
A

anon

Erik said:
class Vec // No need to inherit from vector

I must admit that I missed that tiny detail. I realized it only after
your reply.
My focused was more on making it compile, because after all that was
what he asked for ;)
 
K

Kai-Uwe Bux

Erik said:
std::vetor<T> does not have a virtual destructor and is not designed to
be used as a base class.

Just a nit: Those are two entirely independent issues. The template class
std::iterator<> does not provide a virtual destructor, and its only purpose
is to be used as a base class.

As long as no polymorphic use of std::vector<T>* is anticipated, the
non-virtual destructor won't matter all that much.

In fact, public inheritance from standard containers can be reasonable
substitute for non-aliasing typedefs. E.g., sometimes your have integer
sequences that have different meanings but are all represented as
std::vector<int>. If you just do

typedef std::vector<int> first_kind_of_sequence;
typedef std::vector<int> second_kind_of_sequence;

then your cannot use function overloading based on the sequence type to
distinguish the two. This can be a problem for operator overloading. E.g.,
for the first kind, operator+ could meaningfully denote concatenation,
whereas for the second kind, it could be componentwise addition. In that
case,

struct first_kind_of_sequence : public std::vector<int> {
// constructors
};

struct second_kind_of_sequence : public std::vector<int> {
// constructors
};

can be justified.

The usual recommendation is to either use
private inheritance or have a vector as a member instead.

Correct. However, the reason for this is not so much the non-virtual
destructor but the surprises that can happen when someone has a function
template like:

template < typename T, typename A >
std::vector< T, A > backwards ( std::vector< T, A > const & word );

In this case, an argument of derived type will match but the result will be
of base type.

BTW: In my opinion, it is not all that clear whether this is a valid
argument to shun public inheritance from std::vector. After all, one could
argue that the function is poorly designed and really wants to be done like
this:

template < typename SequenceType >
SequenceType backwards ( SequenceType const & word );



[snip]

Best

Kai-Uwe Bux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top