Thread: maps to structs

  1. #1
    Registered User
    Join Date
    Apr 2011
    Posts
    62

    maps to structs

    hey,
    I'm not sure what I'm doing wrong here and why is my code not compiling. I'm also not sure if there is a better aproach then mine and I'm always open to sugestions.

    so I'm trying to create a class that holds particle data that can be acessed throught the particle ID. for that I decided to try to create a map (I have never used maps before) from ID to a small struct with particle properties.

    Code:
    class ppfromID{
    public:
    	ppfromID(void);
    private:
    	void init(void);
    	static bool initiated;
    	static std::map<int,particle_properties> pp;
    	static std::map<int,double> testmap;
    };
    Code:
    void ppfromID::init(void){
    /**Initiates the class (adds the SM particles and their properties)**/	
    	pp[1]=particle_properties(.32,1);
    }
    the compiler flag undefined reference to `ppfromID::testmap' (amongst other things). I'm entirely sure why this is happening and would like some1 to point me to the right answer.

    thanks in advance

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Your code only declares the statics, but does not define them.

    I'll assume the class definition (the first lump of code) is in a header file, that the definition of ppfromID::init() is in a source file, and the source file #include's the header file somewhere before the definition of ppfromID::init().

    To define pp, you need to place the following line in the source file, after #include'ing the header file
    Code:
    std::map<int,particle_properties> ppfromID::pp;
    This is a definition corresponding to the declaration of pp you have shown.

    Incidentally, it is not the compiler flagging an undefined reference. It would be the linker.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    Registered User
    Join Date
    Apr 2011
    Posts
    62
    oh, I've done that. or rather I've done correctly for pp and then when it didn't work and I created the "testmap" I forgot it (adding non-relevant 1 error line to the flaglist that I obviously chose to post here...)

    ok, to avoid confusions here is all the relevant code (that I should have given from the start):
    Code:
    #ifndef PROJECTNAME_TOOLS_H
    #define PROJECTNAME_TOOLS_H
    #include <map>
    
    struct particle_properties{
    /**This struct holds general paticles data (Mass, Charge, etc).		**/
    /**It's purpose is to hold data of individual particles	that will 	**/
    /**then be called by "ppfromID" (which will hold one				**/
    /**particle_properties object for each particle of the SM).			**/
    /**Exotic particles added will also be stored here.					**/
    public:
    	particle_properties(double,int);
    	particle_properties(double,int,double);
    	double mass;
    	int charge;		//(in units of e/3)
    	double evaporation_weight;
    };
    
    class ppfromID{
    public:
    	ppfromID(void);
    private:
    	void init(void);
    	static bool initiated;
    	static std::map<int,particle_properties> pp;
    	static std::map<int,double> testmap;		//TO BE REMOVED!!!
    };
    Code:
    #include "projectname_tools.h"
    using namespace std;
    
    particle_properties::particle_properties(double m,int q){
    /**CONSTRUCTOR**/
    	mass=m;
    	charge=q;
    	evaporation_weight=0.0;
    }
    
    /**static data for ppfromID**/
    bool ppfromID::initiated=false;
    map<int,particle_properties> ppfromID::pp;
    map<int,double> ppfromID::testmap;
    /****************************/
    
    ppfromID::ppfromID(void){
    /**CONSTRUCTOR**/		
    	if (initiated=false){
    		init();
    		initiated=true;
    	}
    }
    
    void ppfromID::init(void){
    /**Initiates the class (adds the SM particles and their properties)**/	
    	pp[1]=particle_properties(.32,1);
    	testmap[1]=double(.32);
    }
    the error message given is error: no matching function for call to ‘particle_properties::particle_properties(). Indicating that the problem is likely how the struct declaration interacting with the map. I tried this...
    Code:
    	particle_properties temp_pp(.32,1);
    	pp[1]=temp_pp;
    ...with similar results.

    any idea what I'm doing wrong?
    Last edited by killme; 11-05-2013 at 02:08 PM.

  4. #4
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Code:
    pp[1]=temp_pp;
    The very act of writing pp[1] attempts to create a particle object using the default constructor which does not exist and hence why you get the error. You need to either create the default constructor or use the map's insert member function to get around this.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  5. #5
    Registered User
    Join Date
    Apr 2011
    Posts
    62
    yey, it works. thanks for the help.

    just to make sure I'm clear about order of operations (I'm probably not), this line...
    Code:
    pp[1]=particle_properties(.32,1);
    ...translates into:

    1- create an empty pair. (thats what was creating the error).
    2- check if "1" is a key already used.
    3- if the hasn't already been taken copy the (key, struct) pair.
    4-return a pointer to the pair (??).

    is that right? and what would the sequence be if I attempted to add an "already in use key"?

  6. #6
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    pp[1] creates a pair with 1 as the key and a default constructed particle object as the value. Since your default constructor did not exist you got the error. There is no check at this stage that a pair with key 1 exists or not, the pair is simply created as stated in the first sentence. If you wanted to test whether pp[1] existed without actually creating an object with said key, you would need to use the map's find member function. As stated in my earlier post, you can resolve this by either creating a default constructor or using the map's insert member function.

    The assignment step of this statement would simply overwrite the default constructed object with a new particle object. This is also what would happen if you attempted to add an "already in use key", the overwrite of an existing value.

    The return result of the assignment operation is likely the modified particle object referenced by pp[1], not a pointer to the pair.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  7. #7
    Registered User
    Join Date
    Apr 2011
    Posts
    62
    ok, so I finished building most member functions of my class and when It came arrond to testing I ended up with a memory leak.

    a bit of messing about and I found out the program runs as intended (or rather... the class doesn't crash it) if I make the map non-static. any idea why this is happening? all relevant code is above, the crash happends at:
    Code:
    pp[1]=particle_properties(.32,1);
    .

    I don't know if its relevant so I should mention that this class is a static member of a couple of others, perhaps there is some conflict there? (also if you spot the "if(=) bug on the constructor above: it has been fixed)

    sumarizing:
    I have a few classes that have ppfromID as a static member and ppfromID has a map<int,particle_properties> as a static member. and the program crashes when trying to subscribe to the map, however if the map is non-static there is no crash.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I think the best thing to do here is for you to provide the smallest possible compilable example that reproduces the problem.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Registered User
    Join Date
    Apr 2011
    Posts
    62
    Quote Originally Posted by Elysia View Post
    I think the best thing to do here is for you to provide the smallest possible compilable example that reproduces the problem.
    for some reason my simpler example works fine.

    but I managed to work arround the problem without having the map static so I wont bother people anymore with this.

    thanks for the help

  10. #10
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by killme View Post
    for some reason my simpler example works fine.
    That's a sign that you are making assumptions about what the problem is. And that those assumptions are incorrect.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  11. #11
    Registered User
    Join Date
    Apr 2011
    Posts
    62
    Quote Originally Posted by grumpy View Post
    That's a sign that you are making assumptions about what the problem is. And that those assumptions are incorrect.
    yes, I understand. but for now I'm chosing to avoid the problem rather than figure out exactly what it is (any bets on how thats gonna come back to bite me in the ass a couple of weeks from now?).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 01-08-2013, 07:55 AM
  2. Typedef Structs inside Typdef structs
    By gremory in forum C Programming
    Replies: 21
    Last Post: 12-30-2011, 07:48 PM
  3. passing structs & pointers to structs as arguments
    By Markallen85 in forum C Programming
    Replies: 6
    Last Post: 03-16-2004, 07:14 PM
  4. Maps :)
    By Hunter2 in forum Game Programming
    Replies: 4
    Last Post: 09-25-2003, 09:31 AM
  5. STL - Maps
    By jhebert in forum C++ Programming
    Replies: 1
    Last Post: 09-03-2003, 05:13 PM