STL list Usage

M

Mike Copeland

I am trying to learn/use the STL <list> to implement a small
application. I didn't get very far before I got a compile error that
befuddles me. Here's the code:

struct GENCHECK // Gender Check data
{
char genCode;
string firstName;
} gWork;
typedef list<GENCHECK> NAMES;
NAMES genData;
list<GENCHECK>::iterator gIter;

class nameEqual : public unary_function<NAMES, bool>
{ // predicate class to perform structure element comparison
string s;
public:
explicit nameEqual (const string &ss) : s(ss) {}
bool operator() (const NAMES &e) const { return e.firstName == s; }
};

The error (VS 6.0) is:

error C2039: 'firstName' : is not a member of
'list<struct GENCHECK,class std::allocator<struct GENCHECK> >'

and I don't understand why it fails to compile. This code was cobbled
from various sources that by themselves worked, but this doesn't...
I'm open to other ways to achieve my goal: which is to populate a
list (or whatever), search it for a match against the string element of
each object, and adding to the list if I don't find a match. The code
above (so far) is only my attempt to declare the data structures and
define a comparison function. Please advise. TIA
 
I

Ian Collins

Mike said:
I am trying to learn/use the STL <list> to implement a small
application. I didn't get very far before I got a compile error that
befuddles me. Here's the code:

struct GENCHECK // Gender Check data

Use of all caps for types isn't a good idea, it makes them look like macros.
{
char genCode;
string firstName;
} gWork;
typedef list<GENCHECK> NAMES;
NAMES genData;
list<GENCHECK>::iterator gIter;

class nameEqual : public unary_function<NAMES, bool>
{ // predicate class to perform structure element comparison
string s;
public:
explicit nameEqual (const string &ss) : s(ss) {}
bool operator() (const NAMES &e) const { return e.firstName == s; }
};

The error (VS 6.0) is:
That old dog?
error C2039: 'firstName' : is not a member of
'list<struct GENCHECK,class std::allocator<struct GENCHECK> >'

and I don't understand why it fails to compile. This code was cobbled
from various sources that by themselves worked, but this doesn't...

Well this time the compiler is correct, firstName isn't a member of
std::list.
I'm open to other ways to achieve my goal: which is to populate a
list (or whatever), search it for a match against the string element of
each object, and adding to the list if I don't find a match. The code
above (so far) is only my attempt to declare the data structures and
define a comparison function. Please advise. TIA

You'll have to use std::find to search your list to see if the name is
present.
 
G

Greg Herlihy

   I am trying to learn/use the STL <list> to implement a small
application.  I didn't get very far before I got a compile error that
befuddles me.  Here's the code:

struct GENCHECK                        // Gender Check data
{
  char   genCode;
  string firstName;} gWork;

typedef list<GENCHECK> NAMES;
   NAMES         genData;
   list<GENCHECK>::iterator gIter;

class nameEqual : public unary_function<NAMES, bool>
{ // predicate class to perform structure element comparison
        string s;
public:
  explicit nameEqual (const string &ss) : s(ss) {}
  bool operator() (const NAMES &e) const { return e.firstName == s; }

};

Instead of creating a "nameEqual" predicate, I would make it possible
to compare "GENCHECK" objects directly:

struct GENCHECK // Gender Check data
{
char genCode;
string firstName;

bool operator==(const GENCHECK& rhs) const
{
return firstName == rhs.firstName;
}

bool operator<(const GENCHECK& rhs) const
{
return firstName < rhs.firstName;
}

bool operator==(const std::string& rhs) const
{
return firstName == rhs;
}

bool operator<(const std::string& rhs) const
{
return firstName < rhs;
}
} gWork;

With these operators defined, it is now possible to sort the list of
GENCHECK objects (by calling std::list.sort()) or to find a particular
object that matches a string (by calling std::find() on the list).

Greg
 
M

Mike Copeland

I am trying to learn/use the STL said:
Use of all caps for types isn't a good idea, it makes them look like macros.

Fair enough - it just is the style I've been using, but I understand
your comment.
That old dog?

Sorry, it's all I have... 8<{{
Well this time the compiler is correct, firstName isn't a member of
std::list.

Okay, so how can I change to code to reference the structure data?
I'm confused why the compiler believes I'm referring to the std::list
type here...
You'll have to use std::find to search your list to see if the name is
present.

I don't see how I can use str::find to make a test on an element of a
structure. As I understand how std:find works, it operates on a scalar,
not a structure. Please explain how I do this. TIA
 
M

Mike Copeland

Instead of creating a "nameEqual" predicate, I would make it possible
to compare "GENCHECK" objects directly:

struct GENCHECK // Gender Check data
{
char genCode;
string firstName;

bool operator==(const GENCHECK& rhs) const
{
return firstName == rhs.firstName;
}

bool operator<(const GENCHECK& rhs) const
{
return firstName < rhs.firstName;
}

bool operator==(const std::string& rhs) const
{
return firstName == rhs;
}

bool operator<(const std::string& rhs) const
{

bool operator<(const std::string& rhs) const
{
return firstName < rhs;
}
} gWork;
With these operators defined, it is now possible to sort the list of
GENCHECK objects (by calling std::list.sort()) or to find a particular
object that matches a string (by calling std::find() on the list).

Okay, but how do I _use_ these objects in my working code? I added
your code to mine, removed the class/bool that was failing to compile,
and the code now compiles. However, I don't know how to actually engage
the structure functions in my logic. (This is a new concept for me...)
Does genData.find(stringValue) do something here? TIA
 
S

Sashi Asokarajan

Mike said:
class nameEqual : public unary_function<NAMES, bool>
{ // predicate class to perform structure element comparison
string s;
public:
explicit nameEqual (const string &ss) : s(ss) {}
bool operator() (const NAMES &e) const { return e.firstName == s; }
};

NAMES is std::list. And std::list doesn't have firstName.
Change the NAMES to GENCHECK.:
class nameEqual : public unary_function<GENCHECK, bool>
[...]
bool operator() (const GENCHECK &e) const { return e.firstName == s; }
[...]

Why, well find_if will iterate through the given range of your container
holding GENCHECK elements and will do a function call to the provided
predicate object's operator()(GENCHECK&) like this "_predicate()(*iter)".
 
J

James Kanze

Sorry, it's all I have... 8<{{

Both recent VC++ and g++ are very good compilers, and both are
available for free.
Okay, so how can I change to code to reference the structure data?
I'm confused why the compiler believes I'm referring to the std::list
type here...

I'm confused why you'd be confused. The type of e is NAMES
const, and NAMES is a typedef for an instantiation of std::list.
How could using it be anything but an std::list.
I don't see how I can use str::find to make a test on an element of a
structure. As I understand how std:find works, it operates on a scalar,
not a structure. Please explain how I do this. TIA

Find works on anything for which operator== (or operator!=) is
defined, so you can definitely make it work on any user defined
type. Or he may simply have meant std::find_if: I know that I
tend to use std::find as a generic name for both std::find and
std::find_if---which one I actually use will then depend on the
context.
 
N

Nick Keighley

Mike said:
I am trying to learn/use the STL <list> to implement a small
application. I didn't get very far before I got a compile error that
befuddles me. Here's the code:

struct GENCHECK // Gender Check data
{
char genCode;
string firstName;
} gWork;
typedef list<GENCHECK> NAMES;
NAMES genData;
list<GENCHECK>::iterator gIter;

class nameEqual : public unary_function<NAMES, bool>
{ // predicate class to perform structure element comparison
string s;
public:
explicit nameEqual (const string &ss) : s(ss) {}
bool operator() (const NAMES &e) const { return e.firstName == s; }
};

The error (VS 6.0) is:

error C2039: 'firstName' : is not a member of
'list<struct GENCHECK,class std::allocator<struct GENCHECK> >'

and I don't understand why it fails to compile. This code was cobbled
from various sources that by themselves worked, but this doesn't...

I'm open to other ways to achieve my goal: which is to populate a
list (or whatever), search it for a match against the string element of
each object, and adding to the list if I don't find a match. The code
above (so far) is only my attempt to declare the data structures and
define a comparison function.

but you want to compare GENCHECKs (structs) not NAMESs (lists).
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top