пятница, 23 апреля 2010 г.

Pointer to mutable member

Указатели на члены класса позволяют обращаться с членами класса не зная их имени.
struct S {
int i;
};

int S::* pm = &S::i;
Далее эти указатели можно использовать следующим образом:
S cs;
cs.*pm = 10;
Интересно, что нет никакого специального синтаксиса для переменных с квалификатором mutable. Более того, стандарт запрещает использовать указатель на mutable член класса для модификации константного объекта класса (C++ Standard 5.5/5). Следующий код не будет компилироваться:
struct S {
mutable int i;
};
const S cs;
int S::* pm = &S::i; // pm refers to mutable member S::i
cs.*pm = 88;         // ill-formed: cs is a const object
Запрещено это было, видимо, т.к. компилятору сложно отслеживать на какой именно член класса указывает pmmutable или нет. Как и большинство других, это ограничение можно обойти создав обертку:
template<typename T> struct mutable_wrapper { mutable T value; };
Далее используем следующим образом:
struct S {
mutable_wrapper<int> i;
};

const S cs;
mutable_wrapper<int> S::* pm = &S::i;
(cs.*pm).value = 88;
В обертке можно перегрузить операторы приведения типа, чтобы синтаксически скрыть обертку, но это дела вкуса. На мой взгляд лучше явно видеть, когда модифицируются mutable члены класса.

Комментировать в ВКонтакте