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

Recommended Posts

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_[i]->projectid = projectid; // projectid is a member of struct Project. . . ++i; } } The statement 'vec_[i]->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

Share on other sites
Please note that the code statement above:

'project_vec vec_ = new project_vec;'

should be:

'project_vec * vec_ = new project_vec;'

-random

Share on other sites
you want:
(*vec_)[i]->projectid = projectid;

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

edit:
or why not:
vec_->back()->projectid = projectid;

Share on other sites
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_)[i]->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_[i] has type std::vector< Project * >, but for i != 0 is invalid, since it points to incorrect memory.

Enigma

Share on other sites
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

Share on other sites
Quote:
 Original post by random_thinkeras 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 ?

Share on other sites
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

Share on other sites
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.

Create an account

Register a new account

• Partner Spotlight

• Forum Statistics

• Total Topics
627657
• Total Posts
2978472

• 10
• 12
• 22
• 13
• 33