У меня есть следующий код:
#include <iostream>
#include <string>
using namespace std;
struct foo_s {
string a;
string b;
string c;
};
void print_field(foo_s* foo, string foo_s::* field) {
cout << "field: " << field << " - " << foo->*field << endl;
}
int main() {
foo_s my_foo = {
"a",
"b",
"c",
};
print_field(&my_foo, &foo_s::a);
print_field(&my_foo, &foo_s::b);
print_field(&my_foo, &foo_s::c);
return 0;
}
Его вывод:
field: 1 - a
field: 1 - b
field: 1 - c
У меня возникли проблемы с пониманием специфики того, что происходит в функции print_field()
. А именно:
- Какой тип
field
? Я предполагаю, что этоpointer-to-string-foo_s-member
- Почему значение
field
всегда одно и то же (1 в этом случае), ноfoo->*field
дает разные результаты?
В основном, я озадачен # 2. Я предположил, что поле будет "смещением" с начала структуры, а foo->*field
было бы концептуально эквивалентно чему-то вроде
char* ptr = static_cast<char*>(foo);
ptrdiff_t offset = somehow_get_the_byte_offset_from_pointer_to_member(field);
ptr = ptr[offset];
string result = *static_cast<string*>(ptr);
но это кажется отсутствующим, поскольку значение field
не зависит от вызовов. Что мне не хватает? Как именно эта конкретная операция описывается стандартом?