pointer to a vector of pointers to structs...accessing members

Started by
6 comments, last by random_thinker 18 years, 8 months ago
Hi There is probably a simple solution to this; I keep getting the error message "base operand of `->' has non-pointer type", so I know that this is probably a syntax problem. I have a vector or pointers to structs: typedef vector<Project*> project_vec; I use this in my code generally as follows: project_vec vec_ = new project_vec; ...some method.... { int i = 0; while (!in.fail()) { if ( projectid == in.getString() ) { // Initialize memory. vec_->push_back(new Project); vec_->projectid = projectid; // projectid is a member of struct Project. . . ++i; } } The statement 'vec_->projectid = projectid;' results in a g++ 3.3 compiler error message "base operand of `->' has non-pointer type". Have I missed something simple such as not initializing vec_ correctly, ie vec_() ? Thanks --random
--random_thinkerAs Albert Einstein said: 'Imagination is more important than knowledge'. Of course, he also said: 'If I had only known, I would have been a locksmith'.
Advertisement
Please note that the code statement above:

'project_vec vec_ = new project_vec;'

should be:

'project_vec * vec_ = new project_vec;'

-random
--random_thinkerAs Albert Einstein said: 'Imagination is more important than knowledge'. Of course, he also said: 'If I had only known, I would have been a locksmith'.
you want:
(*vec_)->projectid = projectid;


alternativly (gives you range checking to)
vec_->at(i)->projectid = projectid;


edit:
or why not:
vec_->back()->projectid = projectid;
HardDrop - hard link shell extension."Tread softly because you tread on my dreams" - Yeats
First, is there a reason you're using a pointer to a vector rather than just a stack-based or static vector? If there is then the syntax you need to access element i is either (*vec_)->projectid; or vec_->operator[](i)->projectid;. This is because vec_ is a pointer. For a pointer the expression pointer[n] is equivalent to *(pointer + n). So vec_ has type std::vector< Project * >, but for i != 0 is invalid, since it points to incorrect memory.

Enigma
Thanks greatly for your help, DigitalD. I've made the code changes and the error messages have disappeared. I prefer the notation '->at(i)->' simply because I find the path to members easier to follow (and there is range checking of course).

Enigma, I've made this a pointer to a vector because I will eventually be creating a lot of runtime vectors that will be passed around and linked to other structures during runtime, as my program grows. The code syntax is a bit more complex this way, but if class design is suitable then eventually the program should be much more flexible.

Originally, I made the system in terms of static vectors, which worked fine, but I started to run into some problems. So I'm in the process of rewriting these parts of the code. Besides, it helps me learn C++ in more depth as well, which is never a bad thing, in my view.

One of the things that I've noticed is that STL container and string class member access changes significantly when the class becomes a pointer. Simple member access syntax goes out the window. For example, when I recently created a pointer to a string map object, I also changed access as follows:

typedef map<string,string> string_map

as non-pointer:
string_map smap;
smap[key] = value;

as pointer:
string_map * smap;
smap->insert(make_pair(key,value));

These types of changes to STL container pointers are not very well documented in existing books. I've tried to get the best references, such as those by Josuttis and Stroustrup, but this useful info is buried deep, if at all there.

I really like utilizing the STL as much as possible in my work, it solves a lot of problems can make result in elegant code, but I wish that these subtleties were better documented.

--random

--random_thinkerAs Albert Einstein said: 'Imagination is more important than knowledge'. Of course, he also said: 'If I had only known, I would have been a locksmith'.
Quote:Original post by random_thinker
as non-pointer:
string_map smap;
smap[key] = value;

as pointer:
string_map * smap;
smap->insert(make_pair(key,value));


For the pointer version, have you tried (*smap)[key] = value ?

Be aware that map::insert is not equivalent to map::operator[]. map::insert will only ever add a key-value pair to the map and then only if the key is not already in the map. It will never update the value of an existing key-value pair. map::operator[] will either add a key-value pair, or update an existing key-value pair.
#include <iostream>#include <map>int main(){	std::map< int, int > map;	map.insert(std::make_pair(1, 7)); // inserts mapping (1)->(7)	map.insert(std::make_pair(1, 8)); // has no effect	std::cout << map[1] << '\n'; // prints 7	map[2] = 7; // inserts mapping (2)->(7)	map[2] = 8; // updates mapping (2)->(7) to (2)->(8)	std::cout << map[2] << '\n'; // prints 8}

Enigma
Thanks for the tip, Anonymous, I'll try it. I would assume that:

(*smap)[key] = value

will behave the same as the non-pointer:

smap[key] = value;

in that one would be able to update a value, as opposed to the pointer version:

smap->insert(make_pair(key,value));

which Enigma (thanks again) correctly pointed out will add new entries, but not update existing keys.

Cheers,

--random.
--random_thinkerAs Albert Einstein said: 'Imagination is more important than knowledge'. Of course, he also said: 'If I had only known, I would have been a locksmith'.

This topic is closed to new replies.

Advertisement