2017-04-03 5 views
1

私は以下の問題があります(下記のコードを参照してください)。C++ 11バリデーションテンプレートメソッド完全シャドーベースクラスメソッド?

基本クラスから継承するクラスでは、operator()という2つの実装を使用できます。整数をとるもの、「インデックス」を取るものは、単純なIndexクラスを参照してください。私は親クラスでoperator(Index...)を持っている必要がありながら operator(ints...)は、子クラスになります(また、別の戻り値の型を持つ。)

次のコードは、正確な設計ではなく、最小限の作業の例では、最後の問題を説明します。

問題は、私がoperator(Index...)を子クラスに入れた場合、すべてが良好です。私はvec(i)main()の終わりを呼び出すとき

error: no match for call to ‘(Tensor<1, int>) (Index<'i'>&)’ 

:私は、基本クラスに入れた場合、私は、コンパイル・エラーが発生します。私はコンパイラが良い方法を見つけられないことを理解しますが、なぜですか?バリデーショナルテンプレートに関連する「シャドーイング」ルールがいくつかありますか?

ありがとうございます!

using Tensor_traits<order, T, Tensor<order, T>>::operator(); 

または追加してみてくださいTensor

問題に

using Base = Tensor_traits<order, T, Tensor<order, T>>; 
using Base::operator(); 

(Yakkによって提案された(おかげで)他の用途のためにBaseを持っている)

#include <iostream> 
#include <type_traits> 

template<char i> 
class Index{ 
public: 
    Index(){}; 
}; 

template<int order, typename T, class tensor_type> 
class Tensor_traits{ 
    public: 

     //// here, doesn't compile ! ! 
    //template <char i> 
    //T&operator()(Index<i> &ii){ 
    //std::cout << "puet" << std::endl; 
    //} 
}; 


template<int order, typename T> 
class Tensor : public Tensor_traits<order, T, Tensor<order, T>> { 
    private: 
    int data[3] = {1,2,3}; 
    public: 
    Tensor(){}; 

    template <typename... Idx> 
     typename std::enable_if<std::is_same<Idx...,int>::value 
     or std::is_same<Idx...,unsigned int>::value 
     or std::is_same<Idx...,size_t>::value, T&>::type 
     operator()(const Idx&... idx){ 
     return data[0]; //dummy here, actually i do other stuff ! 
     } 

    // here, works! 
    template <char i> 
     T&operator()(Index<i> &ii){ 
     std::cout << "puet" << std::endl; 
     } 

}; 


int main() { 

    Tensor<1,int> vec1; 

    std::cout<< vec1(1) << std::endl;; 

    Index<'i'> i; 

    vec1(i); 
} 

答えて

2

はそれではありません基本クラスはテンプレートクラスです。問題は、派生クラスがoperator()メソッドを継承している別のoperator()メソッド関数を定義しているということです。

これを確認するには、派生クラスで定義されているoperator()を削除してください。usingも含まれていないと、基本クラスのoperator()を使用できます。

usingを使用すると、operator()が基本クラスのoperator()を非表示にするため、両方を使用できるようになります。

+1

私自身はまず、 'Base = Tensor_traits >;' 'Base :: operator();'を使用します。私の脳は即座に 'Tensor_traits > 'が' Tensor 'の基盤であることを即座に証明するほどスマートではないので、' Base'という名前を付けることでより明確になります。 – Yakk

+0

@ Yakk - 複数の基本メソッドに '使用する'の場合にコードの重複を避けるために? – max66

+0

などのコンストラクタなどがあります。CRTPでない場合は、テンプレート引数リスト内で '、class Base = Tensor_traits > 'というようにCRTPが動作しない。 – Yakk

関連する問題