2017-04-03 60 views
1

我有以下問題(請參閱下面的代碼)。C++ 11 variadic模板方法完全影子基類方法?

在繼承自基類的類中,我希望能夠有兩個實現operator()。一個採用整數,一個採用「索引」,參見簡單的Index類。 的operator(ints...)將在子類,而我需要有operator(Index...)在父類(也有不同的返回類型)。

下面的代碼是不準確的設計,但最小的工作示例解釋的最後一個問題。

問題是,如果我把operator(Index...)放在子類中,一切都很好。如果我把它在基類中,我得到一個編譯錯誤:

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

當我打電話vec(i)main()結束。我明白編譯器沒有找到好的方法,但爲什麼?是否有一些與可變參數模板相關的「陰影」規則?

謝謝!

#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

嘗試增加

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

或(由Yakk建議(感謝)有Base用於其他用途)

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

Tensor

的問題不在於基類是一個模板類;問題是派生類定義了另一個operator()方法函數,它隱藏了繼承的方法operator()

要驗證這一點,請刪除派生類中定義的operator(),您可以看到,也沒有using,可以使用基類的operator()

使用using取消隱藏基類的operator(),當在派生類中定義了operator()時,可以同時使用這兩個類。

+1

我自己,我首先使用Base :: Tensor_traits >;'then'使用Base :: operator();'。因爲我的大腦不夠聰明,無法立即證明'Tensor_traits >'只是'Tensor '的基礎,並且通過將其命名爲'Base',其意圖更加清晰。 – Yakk

+0

@Yakk - 也避免代碼重複的情況下使用'多個基地方法? – max66

+0

和構造函數等。如果它不是CRTP,我通常做的就是在模板參數列表中作爲',class Base = Tensor_traits >',但是使用不起作用的CRTP 。 – Yakk