2016-07-13 13 views
0

CRTPを使用して静的多型を実装し、テンプレートパラメータに追加の型を追加したいと思います。基本クラスメンバにアクセスする追加のテンプレートパラメータを持つC++静的ポリモーフィズム/ CRTP

以下のシナリオを提供しますが、派生クラスからBaseメンバーに直接アクセスするにはどうすればよいですか?基本クラスの完全な型を指定せずに可能ですか? ++ 3.8.0出力++ 5.3.1 /打ち鳴らす

#include <iostream> 

template<class Derived, class X> 
struct Base 
{ 
    void set_a(int a) { _a = a; } 
    protected: 
     int _a; 
}; 

template<class X> 
struct Derived: public Base<Derived<X>, X> 
{ 
    int get_a() 
    { 
     // return Base<Derived<X>,X>::_a; // This works! 
     return _a; // error: use of undeclared identifier '_a' 
    } 
}; 

struct foo; 

int main() 
{ 
    Derived<foo> test; 

    auto base_p = static_cast< Base<Derived<foo>, foo>* >(&test); 
    base_p->set_a(42); 

    int a = test.get_a(); 
    std::cout << a << std::endl; 
} 

グラム:

error: use of undeclared identifier '_a' 

答えて

1

あなたのクラスでusing宣言を追加することができます。

template<class X> 
struct Derived: public Base<Derived<X>, X> { 

    using Base<Derived<X>, X>::_a; 

    /* ... */ 

}; 

あなたはまだする必要がそれを一度指定してください。

+0

すてきな回避策!しかし、なぜ私はそれを一度指定しなければならないのか理解したいです! – Albert

+1

@Albertベースクラスがクラスのテンプレートパラメータに依存しているため、これを指定する必要があります。 – Holt

+0

今@Holtは本当の問題を発見した、私は関連する質問を見つけた:http://stackoverflow.com/questions/1239908/why-doesnt-a-derived-template-class-have-access-to-a-base-テンプレートクラスID – Albert

0

スコープでは、_aは宣言されていませんが継承されているため、this->_aを記述して、基本クラスを参照するか、またはBase<Derived<X>, X>::_aを明示的に記述する必要があります。後者はDerivedの定義における

using Base<Derived<X>, X>::_a; 

でインポートすることができます。

TL; DR

this->_aが書かれている場合、thisは固有operator->に一致するようにアップキャストBase<Derived<X>, X>*に自動的にあります。

_aのみが書かれている場合は、unqualified name lookupが実行されます。修飾されていない名前検索はスコープベースであり、継承とは無関係です。あなたの例では、_aは、Derived::get_aでそう_aはありません_aは、コンパイルエラーがトリガされ、発見された

  • Derived::get_a
  • Derived
  • (ファイルスコープ)

で検索されています。

関連する問題