Thread: Typedefining members of structs

  1. #1
    Registered User
    Join Date
    May 2004
    Posts
    73

    Typedefining members of structs

    Hey everyone!

    I program Palm OS for a hobby, and they have a structure in there that is used a lot throughout many programs.

    Code:
    struct RectangleType
    {
        struct
        {
            int X;
            int Y;
        } topLeft;
    
        struct
        {
            int X;
            int Y;
        } extent;
    };
    So to use it, I do...

    Code:
    RectangleType Rect;
    Rect.topLeft.x = 4;
    ...but I've been using my own convention for years, and it dictates that all variable names must have initial caps for every section, like MyStructType instead of Mystructtype or myStructType. And here's RectangleType, with the members that don't comply to my convention. I can deal with this, but it's annoying. Recently though, i thought up a solution. What if I typedef the members to be named something else?

    Code:
    typedef RectangleType::topLeft RectangleType::TopLeft;
    Unfortunately this gives me errors. Can I even do this? If I can, what am I doing wrong? If this isn't possible, is there any other way to make it so I can use my own convention?

    Thanks!

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    So why don't you do this?
    Code:
    struct RectangleType
    {
        struct
        {
            int X;
            int Y;
        } TopLeft;
    
        struct
        {
            int X;
            int Y;
        } Extent;
    };
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2004
    Posts
    73
    I can't do that because RectangleType is part of the system's files. I'm afraid that if I modify it then it'll mess up everything else.

  4. #4
    Software Developer jverkoey's Avatar
    Join Date
    Feb 2003
    Location
    New York
    Posts
    1,905
    Code:
    struct bob
    {
        int foo;
    };
    
    #define Foo foo
    
    int main()
    {
        bob b;
        b.Foo=3;
        return 0;
    }
    That seems to work.

  5. #5
    Registered User
    Join Date
    May 2004
    Posts
    73
    ...but there's no way to do it with typedef?

    It's not only the topLeft to TopLeft and extent to Extent, I was hoping to also do this:

    Code:
    typedef RectangleType::topLeft::x RectangleType::X;
    typedef RectangleType::topLeft::y RectangleType::Y;
    typedef RectangleType::extent::x RectangleType::W;
    typedef RectangleType::extent::x RectangleType::H;
    Macros wouldn't work in this, for spacing reasons.

  6. #6
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Code:
    struct MyRectangleType
    {
        int X;
        int Y;
        int W;
        int H;
    
        operator RectangleType()
        {
            RectangleType rt;
            rt.topLeft.x = X;
            rt.topLeft.y = Y;
            rt.extent.x = W;
            rt.extent.y = H;
            return rt;
        }
    };
    Otherwise, consider breaking your convention; many people are forced to do so whenever they work with 3rd party libraries.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  7. #7
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Quote Originally Posted by Verdagon
    Hey everyone!

    I program Palm OS for a hobby, and they have a structure in there that is used a lot throughout many programs.

    Code:
    struct RectangleType
    {
        struct
        {
            int X;
            int Y;
        } topLeft;
    
        struct
        {
            int X;
            int Y;
        } extent;
    };
    So to use it, I do...

    Code:
    RectangleType Rect;
    Rect.topLeft.x = 4;
    You sure about that?

    Recently though, i thought up a solution. What if I typedef the members to be named something else?

    Code:
    typedef RectangleType::topLeft RectangleType::TopLeft;
    I think the problem is topLeft is not a type. typedef's allow you to declare a synonym for a type. However, topLeft is a variable name--not a type name. In fact, I don't even think topLeft has a type since the struct from which it was formed does not have a name. So, even though it would be a correct application of typedef, you couldn't even typedef topLeft's type if you wanted to.

    Similarly, x is a variable name not a type. x's type is int, so you could typedef int if you wanted, but I don't think you can typedef the name x. Essentially, this is what you are trying to do:
    Code:
    int x;
    typedef x X;
    cout<<X<<endl;
    when what you are allowed to do is this:
    Code:
    typedef int X;
    
    X my_var = 10;
    cout<<my_var<<endl;
    Last edited by 7stud; 04-03-2005 at 02:41 AM.

  8. #8
    Registered User
    Join Date
    May 2004
    Posts
    73
    oops... missed the capitals there... but you get my point.

    I guess i might have to break my convention... The operator RectangleType() method wouldn't work because what happens when I pass it by reference? That's taking the address of a temporary.

    Is there no way to typedef it?

  9. #9
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    I was editing my post when you posted, and I added some stuff. I could be wrong, but I think you are totally misinterpreting what typedef does.

  10. #10
    Registered User
    Join Date
    May 2004
    Posts
    73
    Ok, I see it now... so typedef is impossible for this purpose.

    I guess i'll have to go with breaking my convention, as much as i hate to.

    Although this is tempting:
    Code:
    #define X x
    #define Y y
    #define TopLeft topLeft
    #define Extent extent
    I can't do that though because there are so many places I use the variable names x and y.

    Oh well. Thanks for all your help! I really appreciate you guys taking the time.

  11. #11
    Registered User Kybo_Ren's Avatar
    Join Date
    Sep 2004
    Posts
    136
    I think Hunter2's solution is the best here. I think he really has a great idea.

    Unfortunately I need to 'Spread some around' before I can give him some... :-\

  12. #12
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Well...I suggest you wait for someone to confirm what I posted. I'm just a beginner measured against most of the people here.

  13. #13
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Quote Originally Posted by Kybo_Ren
    I think Hunter2's solution is the best here. I think he really has a great idea.

    Unfortunately I need to 'Spread some around' before I can give him some... :-\
    I was working on encapsulating the structure as well, but I quickly hit a dead end when I realized you couldn't overload the dot operator. Doesn't Hunter's solution require you to do this:
    Code:
    MyRectangleType MyRect;
    MyRect.X = 20;
    MyRect.Y = 30;
    MyRect.W = 40;
    MyRect.H = 50;
    
    RectangleType RT;
    RT = MyRect;
    
    MyRect.X = 10;
    RT = MyRect;
    In other words, everytime you change a member with the dot operator, don't you have to make an assignment for it to be reflected in the system structure? If that's the case, I don't think someone looking to avoid having to type a lower case letter instead of a cap, is going to opt for that as being more convenient.
    Last edited by 7stud; 04-02-2005 at 09:35 PM.

  14. #14
    Registered User Kybo_Ren's Avatar
    Join Date
    Sep 2004
    Posts
    136
    I would simply encapsulate it like this, actually.

    Code:
    const int BADCOORD = -500;
    class MyRectangleType
    {
    
        struct RectangleType rt;
      
    public:
        MyRectangleType();
        int X(int X1 = BADCOORD );
        int Y(int Y1 = BADCOORD );
        int W(int W1 = BADCOORD );
        int H(int H1 = BADCOORD );
    };
    
    MyRectangleType::MyRectangleType()
    {
        rt.topLeft.X = 0;
        rt.topLeft.Y = 0;
        rt.extent.X = 0;
        rt.extent.Y = 0;//or whatever you want the default
    }
    
    int MyRectangleType::X(int X1 )
    {
        if(X1 != BADCOORD)
        {
            rt.topLeft.X = X1;
            return X1;
        }
    
        return rt.topLeft.X;
    }
    
    
    int MyRectangleType::Y(int Y1 )
    {
        if(Y1 != BADCOORD)
        {
            rt.topLeft.Y = Y1;
            return Y1;
        }
    
        return rt.topLeft.Y;
    }
    
    
    int MyRectangleType::W(int W1 )
    {
        if(W1 != BADCOORD)
        {
            rt.extent.X = W1;
            return W1;
        }
    
        return rt.extent.X;
    }
    
    
    int MyRectangleType::H(int H1 )
    {
        if(H1 != BADCOORD)
        {
            rt.extent.Y = H1;
            return H1;
        }
    
        return rt.extent.Y;
    }
    Then when you want to read the current value, just call it with no parameter. When you want to set it, put the value you want as the parameter. Also, modify BADCOORD to suit any bad coordinate value, and change the default values of the stuff you want.

  15. #15
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Hi,

    I think that's a good solution, and it makes it much more convenient to set the struct member values. Instead of having to type:
    Code:
    MyRectangleType A;
    A.topLeft.x = 20;
    the op could just type:
    Code:
    A.X(20);
    I think there are a couple of small problems in your code:

    1)The op incorrectly posted what the system struct looks like: the x an y members are actually lower case.

    2) Presumably at some pt, you have to hand over the struct to the system, and in your code the struct is a private member with no way to access to it.

    I was thinking another solution would be to encapsulate the struct and overload the subscript operator, which would provide an even shorter and maybe even a little more intuitive syntax:
    Code:
    #include<iostream>
    using namespace std;
    
    struct RectangleType
    {
    	struct
    	{
    		int x;
    		int y;
    	} topLeft;
    
    	struct
    	{
    		int x;
    		int y;
    	} extent;
    };
    
    
    class RectType
    {
    public:
    
    	RectangleType rt;
    	int junk;  
    
    	RectType()
    	{
    		rt.topLeft.x = 0;
    		rt.topLeft.y = 0;
    		rt.extent.x = 0;
    		rt.extent.y = 0;
    	}
    
    	int& operator[](int index)
    	{
    		switch (index)
    		{
    		case 1:
    			return rt.topLeft.x;
    			break;
    		case 2:
    			return rt.topLeft.y;
    			break;
    		case 3:
    			return rt.extent.x;
    			break;
    		case 4:
    			return rt.extent.y;
    			break;
    		default:
    			cout<<"index out of bounds"<<endl;
    			return junk;
    		}
    	}
            
    };
    
    int main()
    {
    	RectType A;
    	A[1] = 10;
    	A[2] = 20;
    	A[3] = 30;
    	A[4] = 40;
    	
    	cout<<A.rt.extent.x<<endl;
    
    	return 0;
    }
    I wasn't sure how to handle the default in the switch: the return type has to be an int variable that can be an l-value, so I just added a junk member variable, and the default returns that.

    edit: Hmmm...I guess the syntax isn't shorter--it requires an identical number of characters as calling your functions.
    Last edited by 7stud; 04-03-2005 at 03:05 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. dynamicly adding data members to structs
    By ITAmember in forum C Programming
    Replies: 11
    Last Post: 06-01-2009, 03:26 PM
  2. Structs, members, and casting
    By Nick Howes in forum C Programming
    Replies: 4
    Last Post: 03-05-2008, 12:54 PM
  3. alignment (classes, structs, members)
    By Raven Arkadon in forum C++ Programming
    Replies: 5
    Last Post: 04-07-2006, 06:51 AM
  4. accessing members in nested structs
    By amidstTheAshes in forum C Programming
    Replies: 2
    Last Post: 03-23-2005, 02:00 PM
  5. Passing members of structs to functions
    By CV3 in forum C Programming
    Replies: 6
    Last Post: 09-23-2004, 01:56 PM