7

次のコード (単純な CRTP クラス階層) があるとします。入力を節約するために基本クラスの型を typedef したい (実際のコードでは、基本クラスの型を複数回使用し、基本クラスはいくつかのテンプレート パラメーターを受け取ります)。実装は非公開です。

template< class D >
class Base
{

public:

    void foo() { *static_cast< D * >(this)->foo_i(); }

};

template< class T >
class Derived : public Base< Derived< T > >
{

public:

    typedef class Base< Derived< T > > BaseType;

private:

    // This here is the offending line 
    friend class BaseType;

    void foo_i() { std::cout << "foo\n"; }

};

Derived< int > crash_dummy;

クラン 言います:

[...]/main.cpp:38:22: error: elaborated type refers to a typedef
    friend class BaseType;
             ^
[...]/main.cpp:33:44: note: declared here
    typedef class Base< Derived< T > > BaseType;

これを修正するにはどうすればよいですか? フレンド クラスの宣言のためだけにすべてを入力するだけで問題なく動作することに気付きましたが、ほんの少しの重複したコードでも少し不快に感じるので、よりエレガントな「適切な」ソリューションを探しています。 .

4

3 に答える 3

11

これは C++03 では不可能だと思いますが、 C++11 に追加されたclassので、キーワードを単純に省略できます。

friend BaseType;
于 2013-01-31T10:38:57.057 に答える
3

C++11 のみを有効にして使用するfriend BaseType

C++03 の typedef でフレンド クラスを使用することはできません。

クラスのフレンド宣言では、精巧な型指定子を使用する必要があります(101)。

101) 精巧な型指定子のクラスキーが必要です。

elaborated-type-specifier:

class-key ::opt nested-name-specifieropt identifier

class-key ::opt nested-name-specifieropt templateopt template-id

enum ::opt nested-name-specifieropt identifier

typename ::opt nested-name-specifier identifier

typename ::opt nested-name-specifier templateopt template-id
于 2013-01-31T10:39:10.930 に答える
1

実際には C++11 よりも前の C++ で実行できますが、最初にこの「ヘルパー」を宣言するという行に沿って、かなり手の込んだ (笑) 回避策が必要です。

template< class T > struct ParamTypeStruct { typedef T ParamType; };

次に、あなたの友人の宣言:

friend class ParamTypeStruct< BaseType >::ParamType;
于 2013-10-14T17:35:35.747 に答える