1. ホーム
  2. c++

[解決済み] C++で自律的なメンバ型 `self` を実装することはできますか?

2022-10-26 04:14:08

質問

C++ 欠如 に相当する PHP の self キーワード で、これは囲むクラスの型として評価されます。

クラス単位でごまかすのは簡単ですが

struct Foo
{
   typedef Foo self;
};

と書く必要があったのですが Foo をもう一度。いつかこれを間違えてサイレントバグを起こすかもしれませんね。

をいくつか組み合わせて使うことはできますか? decltype と友達を組み合わせて、これを自律的に動作させることはできますか? すでに以下を試してみました。 しかし this はその場所では有効ではありません。

struct Foo
{
   typedef decltype(*this) self;
};

// main.cpp:3:22: error: invalid use of 'this' at top level
//     typedef decltype(*this) self;

(に相当する部分については気にしないことにします)。 static と同じことをしますが、レイトバインディングです)。

どのように解決するのですか?

Fooの型を繰り返さずに行う方法を紹介します。

template <typename...Ts>
class Self;

template <typename X, typename...Ts>
class Self<X,Ts...> : public Ts...
{
protected:
    typedef X self;
};

#define WITH_SELF(X) X : public Self<X>
#define WITH_SELF_DERIVED(X,...) X : public Self<X,__VA_ARGS__>

class WITH_SELF(Foo)
{
    void test()
    {
        self foo;
    }
};

から派生させたい場合は Foo から派生させたい場合は、マクロ WITH_SELF_DERIVED を次のように使用します。

class WITH_SELF_DERIVED(Bar,Foo)
{
    /* ... */
};

可変長テンプレートと可変長マクロのおかげで、好きなだけ多くのベースクラスで多重継承を行うこともできます。

class WITH_SELF(Foo2)
{
    /* ... */
};

class WITH_SELF_DERIVED(Bar2,Foo,Foo2)
{
    /* ... */
};

gcc 4.8とclang 3.4で動作することを確認しています。