Pointer to struct member

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.
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;
	}
}
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;
}
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
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
@Framework, That looks perfect. I didn't know it was possible to do that. Nice to learn new things. :)
Last edited on
Peter, could you explain to me exactly what the question is?
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 ?
closed account (zb0S216C)
Peter87: You can do it with member functions, too :) Though, the syntax looks quite similar to a burst mattress.

Wazzak
:( I want to know why your awkward code is needed to loop through a specific member of a structure.
:( 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
closed account (zb0S216C)
LB wrote:
"And don't you need to take the address of STRUCT::LastName ?"

Sorry, another typo.

Wazzak
Last edited on
Oh. So the op specifically wants a pointer to member. Interesting.
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
Topic archived. No new replies allowed.