6

次のコードを検討してください。

struct Foo
{
    mutable int m;

    template<int Foo::* member> 
    void change_member() const {
        this->*member = 12; // Error: you cannot assign to a variable that is const
    }

    void g() const {
    change_member<&Foo::m>();
    }
};

コンパイラはエラー メッセージを生成します。問題は、メンバーmが可変であるため、変更が許可されていることmです。しかし、関数シグネチャは変更可能な宣言を隠しています。

このコードをコンパイルするためにポインターから可変メンバーへのデカルを行う方法は? それが不可能な場合は、標準 C++ にリンクしてください。

4

1 に答える 1

9

このコードは、C++ 標準 5.5/5 によると、形式が正しくありません。

cv 修飾に関する制限、およびオペランドの cv 修飾子を組み合わせて結果の cv 修飾子を生成する方法は、5.2.5 で与えられた E1.E2 の規則と同じです。[注: const クラス オブジェクトを変更するために可変メンバーを参照するメンバーへのポインターを使用することはできません。 例えば、

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

]

次のように、ラッパー クラスを使用してこの問題を回避できます。

template<typename T> struct mutable_wrapper { mutable T value; };

struct Foo
{
    mutable_wrapper<int> m;

    template<mutable_wrapper<int> Foo::* member> 
    void change_member() const {
        (this->*member).value = 12; // no error
    }

    void g() const {
    change_member<&Foo::m>();
    }
};

しかし、コードの再設計を検討する必要があると思います。

于 2010-04-20T12:57:49.993 に答える