可視

2016-04-15 6 views
3

私は、次のコードをコンパイルする問題が、それは単に以下を参照、コンパイルエラーになります。可視

私が理解できなかったもの: 自分のクラスAny自体がテンプレートクラスでない場合は、すべて正常に動作します。 (あなたはこれにサンプルコードの行のコメントを解除することができます。

AnyBASE_Tが長く表示されていないテンプレートである場合。再びそれを目に見えるようにするコツはありますか?

を私はBASE_Tを必要とするのはなぜ?などのことができます。 ConcatHelperテンプレートは、このテンプレートのバリデーシックリストの一部であるすべてのタイプのクラスを作成します。実際のコードはここではもっと重要ですが、この例では重要ではありません。何度も何度もテンプレートパラメータ

使用済みのコンパイラ:。。gcc6のG ++ 5.3.1と最新のスナップショット

#include <iostream> 

class F {}; 

template<typename T> 
class FReader 
{ 
    public: 
     FReader(F&){} 
}; 

template<typename T> class A { }; 
template<typename T> class B { }; 


template < typename FILETYPE, typename Base, typename ...Tail> class ConcatHelper; 

template <typename FILETYPE, typename Base, typename Head, typename ...Tail> 
class ConcatHelper< FILETYPE, Base, Head, Tail...>: public Head, public ConcatHelper< FILETYPE, Base, Tail... > 
{ 
    public: 
     typedef ConcatHelper< FILETYPE, Base, Head, Tail...> BASES_T; 

     ConcatHelper(FILETYPE &_is): ConcatHelper< FILETYPE, Base, Tail... >(_is){} 
}; 

template<typename FILETYPE, typename Base> 
class ConcatHelper<FILETYPE, Base>: public Base 
{ 
    public: 
    ConcatHelper(FILETYPE& _i): Base(_i){} 
}; 

//class OUTER_MASTER{}; 
template <typename OUTER_MASTER> 
class Any: public ConcatHelper<F, FReader<OUTER_MASTER>, A<OUTER_MASTER>,B<OUTER_MASTER>> 
{ 
    public: 
     Any(F& is): BASES_T (is) {} // did not compile 
     //Any(F& is):ConcatHelper<F, FReader<OUTER_MASTER>, A<OUTER_MASTER>,B<OUTER_MASTER>>(is) {} // compiles 
}; 

int main() 
{ 
    F f; 
    Any<int> gr(f); 
    //Any gr(f); 

} 

結果:

error: class 'Any<OUTER_MASTER>' does not have any field named 'BASES_T' 

私は変更する場合:

Any(F& is): BASES_T (is) {} 

Any(F& is): std::remove_reference<decltype(*this)>::type::BASES_T (is) {} 

にしかし、これは本当に有効なC++コードのですか?

+0

これはMSVCではなく、クランやGCCでコンパイルありません。バグや文書化されていない機能がおそらく... – wally

答えて

4

あなたが使用するタイプ名を修飾する必要があるテンプレート派生クラスからの型名を使用します。 C++標準として

は、(14.6.2/3)と言う:クラステンプレートまたはクラステンプレートのメンバーの定義において

、 クラステンプレートの基本クラスは、に依存している場合 基本テンプレートのスコープは、クラステンプレートまたはメンバの定義時点で 、または の定義時点で検査されません。クラス名とコンストラクタの修飾

は動作します:

template <typename OUTER_MASTER> 
class Any: public ConcatHelper<F, FReader<OUTER_MASTER>, A<OUTER_MASTER>,B<OUTER_MASTER>> 
{ 
    public: 
     Any(F& is): Any::BASES_T(is) {} 
}; 
+0

アップス、これは私の回避策の明確な単純化された変形です:-)ありがとう!私たちが思ったように、世界の何かがはるかに簡単です! – Klaus