yohhoyの日記

技術的メモをしていきたい日記

Passkey Idiom

他クラスに対して “メンバ関数単位でのアクセス制限” を実現するイディオム。

template <class T>
class Passkey {
  friend T;
  Passkey() {}
};

class A;
class B;

class C {
public:
  // クラスAに対してのみ公開
  void mfA(Passkey<A>, int arg);
  // クラスBに対してのみ公開
  void mfB(Passkey<B>, int arg);
};

class A {
public:
  void f(C& c) {
    c.mfA({}, 1);  // OK
    c.mfB({}, 2);  // NG
  }
};

上記コードでPasskeyコンストラクタを= defaultでユーザ宣言すると、C++17以前ではイディオムの意図通りに動作しない。コンストラクタのprivateアクセス制限を無視してPasskey<T>の集成体初期化(aggregate initialization)に成功してしまう問題があり、C++20で言語仕様が変更された。

関連URL