Compilation errors in a vector problem

A

Ankur Arora

While coding an algorithm for the following problem, there are a few
compilation errors that I don't completely understand. The errors
are:-

error C2839: invalid return type 'Human **' for overloaded 'operator -

error C2039: 'PrintFamilyTree' : is not a member of
'std::_Vector_iterator<_Ty,_Alloc>'
1> with
1> [
1> _Ty=Human *,
1> _Alloc=std::allocator<Human *>
1> ]

I think C2839 probably triggers C2039, however I'm unable to pinpoint
the problem.

Here's the code and solution.
-----------------------------------------------------------------------------------------------------------
Implement method PrintFamilyTree() that prints out the Name and
Generation of the tree.

Output should resemble
Name: Jan Generation:0
Name: Mike Generation:1
Name: Greg Generation:2
Name: Carol: Generation: 2
Name: Peter Generation: 3
Name: Marcia Generation: 3
Name: Bobby Generation: 1


class Human : public std::vector<Human *>
{
public:
Human(const std::string &name) : m_Name(name) {};
virtual void PrintFamilyTree(const short &generation = 0) const;
protected:
std::string m_Name;
};

class Male: public Human
{
public:
Male(const std::string &name) : Human(name) {};
};

class Female: public Human
{
public:
Female(const std::string &name) : Human(name) {};
};

void main()
{
Male m1("Mike"), m2("Greg"), m3("Peter"), m4("Bobby");
Female f1("Carol"), f2("Marcia"), f3("Jan");
m1.push_back(&m2);
f1.push_back(&m3);
f1.push_back(&f2);
m1.push_back(&f1);
f3.push_back(&m1);
f3.push_back(&m4);
f3.PrintFamilyTree();
}

Solution
------------

void PrintFamilyTree(const short& generation)
{
printf("Name : %s Generation = %d\n", m_Name.c_str(),generation);
vector<Human*>::iterator it;
for (it = this.begin(); it< this.end() ;it++)
{
it->PrintFamilyTree(generation+1);
}
}
 
V

Victor Bazarov

Ankur said:
While coding an algorithm for the following problem, there are a few
compilation errors that I don't completely understand. The errors
are:-

error C2839: invalid return type 'Human **' for overloaded 'operator -

error C2039: 'PrintFamilyTree' : is not a member of
'std::_Vector_iterator<_Ty,_Alloc>'
1> with
1> [
1> _Ty=Human *,
1> _Alloc=std::allocator<Human *>
1> ]
[..]

void PrintFamilyTree(const short& generation)
{
printf("Name : %s Generation = %d\n", m_Name.c_str(),generation);
vector<Human*>::iterator it;
for (it = this.begin(); it< this.end() ;it++)

What's "this" doing here? As I understand the language rules, the line
above should not compile. Or is that function inside a class
definition? Then it still not supposed to compile since 'this' is a
pointer and with a pointer '.' cannot be used (pointers don't have members).

Also, it is more idiomatic to use != when comparing an iterator to the
end of the container being iterated, not <.
{
it->PrintFamilyTree(generation+1);
}
}

Are you sure?

V
 
A

Alf P. Steinbach

* Ankur Arora:
While coding an algorithm for the following problem, there are a few
compilation errors that I don't completely understand. The errors
are:-

error C2839: invalid return type 'Human **' for overloaded 'operator -

error C2039: 'PrintFamilyTree' : is not a member of
'std::_Vector_iterator<_Ty,_Alloc>'
1> with
1> [
1> _Ty=Human *,
1> _Alloc=std::allocator<Human *>
1> ]

I think C2839 probably triggers C2039, however I'm unable to pinpoint
the problem.

Here's the code and solution.
-----------------------------------------------------------------------------------------------------------
Implement method PrintFamilyTree() that prints out the Name and
Generation of the tree.

Output should resemble
Name: Jan Generation:0
Name: Mike Generation:1
Name: Greg Generation:2
Name: Carol: Generation: 2
Name: Peter Generation: 3
Name: Marcia Generation: 3
Name: Bobby Generation: 1


class Human : public std::vector<Human *>
{
public:
Human(const std::string &name) : m_Name(name) {};
virtual void PrintFamilyTree(const short &generation = 0) const;
protected:
std::string m_Name;
};

class Male: public Human
{
public:
Male(const std::string &name) : Human(name) {};
};

class Female: public Human
{
public:
Female(const std::string &name) : Human(name) {};
};

void main()

Your instructor or book should not teach you such bad habits.

'void' is not permitted as result type of 'main'.

Not in C, not in C++.

Use 'int main'.

{
Male m1("Mike"), m2("Greg"), m3("Peter"), m4("Bobby");
Female f1("Carol"), f2("Marcia"), f3("Jan");
m1.push_back(&m2);
f1.push_back(&m3);
f1.push_back(&f2);
m1.push_back(&f1);
f3.push_back(&m1);
f3.push_back(&m4);
f3.PrintFamilyTree();
}

Solution

This does not match the declaration in the class. Worse, you're not definining
the class' member routine but some free-standing routine.

To get going on this, replace above with

void Human::printFamilyTree(const short& generation) const

The logic below is sound, i.e. it'll work, but the coding is ungood.

You'll get a host of compilation errors. Just fix them one by one.

{
printf("Name : %s Generation = %d\n", m_Name.c_str(),generation);
vector<Human*>::iterator it;
for (it = this.begin(); it< this.end() ;it++)
{
it->PrintFamilyTree(generation+1);
}
}


Cheers & hth.,

- Alf
 
A

Ankur Arora

Ankur said:
While coding an algorithm for the following problem, there are a few
compilation errors that I don't completely understand. The errors
are:-
error C2839: invalid return type 'Human **' for overloaded 'operator -
error C2039: 'PrintFamilyTree' : is not a member of
'std::_Vector_iterator<_Ty,_Alloc>'
1>        with
1>        [
1>            _Ty=Human *,
1>            _Alloc=std::allocator<Human *>
1>        ]
[..]
void PrintFamilyTree(const short& generation)
{
  printf("Name : %s Generation = %d\n", m_Name.c_str(),generation);
  vector<Human*>::iterator it;
  for (it = this.begin(); it< this.end() ;it++)

What's "this" doing here?  As I understand the language rules, the line
above should not compile.  Or is that function inside a class
definition?  Then it still not supposed to compile since 'this' is a
pointer and with a pointer '.' cannot be used (pointers don't have members).

Also, it is more idiomatic to use != when comparing an iterator to the
end of the container being iterated, not <.
  {
     it->PrintFamilyTree(generation+1);
  }
}

Are you sure?

V

Oh. Sorry for pasting the wrong code.
Yes 'PrintFamilyTree' is a member function and I'm using 'this->' as
against 'this.'.
Yes those are the line which the compiler is reporting errors on.
But I suspect that the line

for (it = this->begin(); it< this->end() ;it++)

is probably where the errors are originating from.
From looking at the class hierarchy (i.e. how its derived from
std::vector<Human*>, do you think this is the right way to iterate
over the elements?
 
V

Victor Bazarov

Ankur said:
Oh. Sorry for pasting the wrong code.
Yes 'PrintFamilyTree' is a member function and I'm using 'this->' as
against 'this.'.
Yes those are the line which the compiler is reporting errors on.
But I suspect that the line

for (it = this->begin(); it< this->end() ;it++)

is probably where the errors are originating from.
From looking at the class hierarchy (i.e. how its derived from
std::vector<Human*>, do you think this is the right way to iterate
over the elements?

It's the right way. The only problem is that when you dereference 'it',
the resulting value is still a pointer (since 'this' is a vector of
pointers to Human). So you need two indirections here:

(*it)->PrintFamilyTree(generation+1);

V
 

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,770
Messages
2,569,584
Members
45,077
Latest member
SangMoor21

Latest Threads

Top