Hi, I was wondering if anyone could help me. I'm constantly getting the following compiler message:

138 driver.cpp 'class pclass' has no member named 'surname'
138 driver.cpp 'class pclass' has no member named 'name'

on the following lines:

138 for (i = person[surname][name].begin(), i != person[surname][name].end(), ++i) {
139   for (iter = person[*i.first][name].begin(), iter != person[*i.first][name].end, ++iter) {

i and iter are iterators that have to loop through the contents of a two dimentional map named person using a nested for-loop. They are defined as follows:

typedef map<string, map<string, Person_class> > pclass;
pclass::const_iterator i;
map<string, Person_class>::const_iterator iter; 
pclass person;

and the definition for the Person_class defined in the header file:

//Person class declaration
class Person_class {

public:

       //Accessor Functions

       std::istream& read_surname(std::istream&);
       std::istream& read_name(std::istream&);
       std::istream& read_phone(std::istream&);
       std::istream& read_age(std::istream&);
       std::istream& read_weight(std::istream&);
       std::string get_name() const { return name; }
       std::string get_surname() const { return surname; }
       std::string get_phone() const { return phone; }
       int get_age() const { return age; }
       double get_weight() const { return weight; }

       //Constructor Functions

       Person_class();
       Person_class(std::istream&);

private:

        std::string surname;
        std::string name;
        std::string phone;
        int age;
        double weight;
    };

I'm only getting the error on line 138 though, but that's maybe because the compiler ignores the rest of the for-loop...

I thought the reason for the errors could be the fact that surname and name are private sections of the Person_class, but replacing them
with the get_surname() and get_name() functions like :

138 for (i = person[person.get_surname()][person.get_name()].begin(), i != person[surname][name].end(), ++i) {
139 for (iter = person[*i.first][person.get_name()].].begin(), iter != person[*i.first][person.get_name()].].end, ++iter) {

yield the following compiler errors:

138 driver.cpp 'class pclass' has no member named 'get_surname'
138 'class pclass' has no member named 'get_name'

I'm using Dev C++ on Windows XP(Service Pack 2)

Here's a copy of the first few lines of my compiler log:

Compiler: Default compiler
Building Makefile: "C:\Documents and Settings\Steven\Desktop\CTI\C++ Unit 3\Finished Project\Makefile.win"
Executing make...
make.exe -f "C:\Documents and Settings\Steven\Desktop\CTI\C++ Unit 3\Finished Project\Makefile.win" all
g++.exe -c driver.cpp -o driver.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"C:/Dev-Cpp/include/c++/3.4.2/backward" -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32" -I"C:/Dev-Cpp/include/c++/3.4.2" -I"C:/Dev-Cpp/include" driver.cpp: In member function `void Driver_class::switch_function(int)':
driver.cpp:138: error: 'class pclass' has no member named 'get_surname'
driver.cpp:138: error: 'class pclass' has no member named 'get_name'

If anybody could please help me out, that would be awesome...

Thanx
Steven

Dani AI

Generated

Two separate issues are visible in the original posts. First, person is a map-of-maps, not a Person_class, so expressions like person.get_name() or person[surname][name] (when surname/name are members of Person_class) are conceptually wrong: the get_... accessors belong to a Person_class object, not to the outer container. Second, the for header in the examples used commas where semicolons belong and used the wrong way to reach the inner map (the inner map is the second member of the outer iterator's pair).

A clear, correct nested-iteration pattern (C++03-style) looks like this:

for (pclass::const_iterator outer = person.begin(); outer != person.end(); ++outer) {
    const std::map<std::string, Person_class>& inner = outer->second;
    for (std::map<std::string, Person_class>::const_iterator innerIt = inner.begin();
         innerIt != inner.end(); ++innerIt) {
        const Person_class& p = innerIt->second;
        // call p.get_name(), p.get_surname(), etc.
    }
}

Notes and cautions:

  • Use outer->second or (*outer).second to access the inner map; outer->first is the outer key (surname if that is how keys are arranged).
  • map::operator[] will insert a default-constructed element if the key is missing; use find() when only checking/reading, or at() (C++11+) to avoid silent insertion.
  • Prefer const & to avoid copying Person_class objects. In modern C++ prefer range-based loops or auto for terser code and fewer iterator-typing mistakes.

pointed in the right direction about iterating the outer map; the corrected example above fixes the syntax and shows how to reach the Person_class instances so get_name()/get_surname() can be called (the original errors came from trying to call those on the outer map itself, as observed).

Recommended Answers

All 2 Replies

'person' is a map of maps, not a Person_class, so naturally it won't have those members. person["somestring"]["somestring"] would return (or set) a Person_class, however, so trying:

person[person.get_surname()][person.get_name()].begin()

Wouldn't make sense (Person_class doesn't have a begin() method). I suppose you could do (untested):

for (i = person.begin(); i != person.end(), ++i) {
  for (iter = i->begin(), iter != i->end(), ++iter) {

I'd like to suggest more of a solution, but I really have no idea what you're trying to do (and if you need to iterate over the entire "person" container, a map might not be the best solution)

Thanx

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.