Pointer to struct member

Apr 24, 2012 at 3:45pm
What I'm trying to do is have a pointer assigned to a member of an array of structs so that I can loop through them.

Something along the lines of this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct STRUCT
{
	string LastName;
	string FirstName;
};

int main()
{
        STRUCT Struct[3];

	int* Option = Struct.LastName;

	for (int i = 0; i <= 2; i++)
	{
		cout << Struct[i].Option << endl;
	}
	return 0;
}


Keep in mind that this is only an example.
Apr 24, 2012 at 4:36pm
I think it is possible to do this by calculating memory offsets and such but it will be a bit hackish. Maybe you can try to avoid it. You could have last and first names in an array. That way you can use an index to decide if it should be first name or last name.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
enum
{
	FIRST_NAME,
	LAST_NAME
};
struct STRUCT
{
	string name[2];
};

int main()
{
        STRUCT Struct[3];

	int iName = LAST_NAME;

	for (int i = 0; i < 3; i++)
	{
		cout << Struct[i].name[iName] << endl;
	}
}
Apr 24, 2012 at 5:10pm
You could use a functor for this as well:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
struct STRUCT
{
	std::string LastName;
	std::string FirstName;
};



struct print_last_name
{
	void operator()(const STRUCT &structure)
	{
		std::cout << structure.LastName << std::endl;
	}
};

struct print_first_name
{
	void operator()(const STRUCT &structure)
	{
		std::cout << structure.FirstName << std::endl;
	}
};


int main()
{
	STRUCT myarray[3];
	myarray[0].FirstName = "John";
	myarray[0].LastName = "Smith";
	myarray[1].FirstName = "Jane";
	myarray[1].LastName = "Doe";
	myarray[2].FirstName = "Bobby";
	myarray[2].LastName = "Miller";

	std::for_each(myarray, myarray + 3, print_first_name()); //1 first name example.
	std::for_each(myarray, myarray + 3, print_last_name()); //2 last name example
        //You can still use index like you did in your example...
	for(int i = 0; i < 3; ++i)
	{
		print_first_name()(myarray[i]);  //3 first name example
	}
	return 0;
}
Apr 24, 2012 at 5:28pm
closed account (zb0S216C)
Peter87 wrote:
"I think it is possible to do this by calculating memory offsets and such but it will be a bit hackish."

Not to mention that alignment is compiler-specific. Have you tried using a pointer-to-a-member? It's probably one of the safest ways to do what you want:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct STRUCT
{
	std::string LastName;
	std::string FirstName;
};

typedef std::string(STRUCT:: *PtrToLastName);

int main()
{
        STRUCT Struct[3];

	PtrToLastName LastName(&STRUCT::LastName);

	for (int i = 0; i <= 2; i++)
		std::cout << Struct[i].*LastName << std::endl;
	return 0;
}

...or am I missing something?

Edit:

Note that a pointer-to-a-member isn't bound to 1 particular instance of STRUCT:

1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
    STRUCT A, B, C;

    PtrToLastName LastName(&STRUCT::LastName);
    
    std::cout << A.*LastName << '\n';
    std::cout << B.*LastName << '\n';
    std::cout << C.*LastName << std::endl;

    return(0);
}


LB: Oops. Corrected.

Wazzak
Last edited on Apr 24, 2012 at 6:14pm
Apr 24, 2012 at 5:42pm
LOL. I think the question is being asked wrong.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct STRUCT
{
	string LastName;
	string FirstName;
};

int main()
{
        STRUCT Struct[3];

	//int* Option = Struct.LastName;

	for (int i = 0; i <= 2; i++)
	{
		cout << Struct[i].LastName << endl;
	}
	return 0;
}


Hmm. Interesting.. This doesn't work.. (I've never used structs. shame on me.)
So anyone know why we can't do it like this?


Nevermind. I think it does work. But, I have a feeling it doesn't answer the question.
Last edited on Apr 24, 2012 at 5:50pm
Apr 24, 2012 at 5:44pm
@Framework, That looks perfect. I didn't know it was possible to do that. Nice to learn new things. :)
Last edited on Apr 24, 2012 at 5:45pm
Apr 24, 2012 at 5:50pm
Peter, could you explain to me exactly what the question is?
Apr 24, 2012 at 5:50pm
Framework wrote:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct STRUCT
{
	std::string LastName;
	std::string FirstName;
};

typedef std::string(STRUCT:: *PtrToLastName);

int main()
{
        STRUCT Struct[3];

	PtrToLastName LastName(STRUCT::LastName);

	for (int i = 0; i <= 2; i++)
		std::cout << Struct[i].*Option << std::endl;
	return 0;
}
Where does "Option" come from? And don't you need to take the address of STRUCT::LastName ?
Apr 24, 2012 at 5:51pm
closed account (zb0S216C)
Peter87: You can do it with member functions, too :) Though, the syntax looks quite similar to a burst mattress.

Wazzak
Apr 24, 2012 at 5:54pm
:( I want to know why your awkward code is needed to loop through a specific member of a structure.
Apr 24, 2012 at 6:03pm
:( I want to know why your awkward code is needed to loop through a specific member of a structure.


It's not, you can easily do:
1
2
3
4
for(int i = 0; i < size; ++i)
{
    cout << mystruct[i].FirstName << endl;
}


Maybe the OP was asking something else...

On the Flip side, I like Framework's suggestion, haven't used pointers to members myself.
Last edited on Apr 24, 2012 at 6:05pm
Apr 24, 2012 at 6:06pm
closed account (zb0S216C)
LB wrote:
"And don't you need to take the address of STRUCT::LastName ?"

Sorry, another typo.

Wazzak
Last edited on Apr 24, 2012 at 6:08pm
Apr 24, 2012 at 6:07pm
Oh. So the op specifically wants a pointer to member. Interesting.
Apr 24, 2012 at 6:10pm
Btw. I get a compiler error with Framework's code. It has trouble finding LastName, as it is not a static member of STRUCT.

Now it works. Sweet.
Last edited on Apr 24, 2012 at 6:11pm
Topic archived. No new replies allowed.