2017-04-03 7 views
1

다음과 같은 문제가 있습니다 (아래 코드 참조).C++ 11 가변적 템플릿 메서드가 완전히 그림자 기본 클래스 메서드?

기본 클래스에서 상속하는 클래스에서 operator()의 두 가지 구현을 수행 할 수 있기를 원합니다. "인덱스"를 취하는 정수를 취하는 정수는 간단한 Index 클래스를 참조하십시오. 내가 부모 클래스의 operator(Index...)이 필요 동안 operator(ints...)는 자식 클래스에있을 것입니다 (또한 다른 반환 유형.)

아래의 코드는 정확한 디자인이 아니라 최소한의 작업 예를 최종 문제를 설명 .

문제는 자식 클래스에 operator(Index...)을 입력하면 모든 것이 좋습니다. 내가 vec(i)main()의 끝을 호출 할 때

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

: 나는 기본 클래스에 넣어, 내가 컴파일 오류가 발생합니다. 나는 컴파일러가 좋은 방법을 찾지 못한다는 것을 이해하지만, 왜 그런가? variadic 템플릿과 관련된 "섀도 잉"규칙이 있습니까?

감사합니다.

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()을 사용할 수 있습니다.

기본 클래스의 operator()을 그대로 사용하면 operator()이 파생 클래스에 정의되어 있으므로 둘 다 사용할 수 있습니다.

+1

나 자신이 먼저'Using Base = Tensor_traits >;''Base :: operator();'를 사용했다. 뇌가 똑똑하지 않아서'Tensor_traits >'는'Tensor '의 기초에 불과하며'Base'라는 이름을 붙이면 더 명확 해집니다. – Yakk

+0

@Yakk - 또한 여러 기본 방법에 대해 '사용'의 경우 코드 중복을 방지 하시겠습니까? – max66

+0

그리고 생성자 등에서. CRTP가 아니라면, 템플릿 인자 목록 내에서', class Base = Tensor_traits >'와 같은 작업을하지만 CRTP는 작동하지 않습니다. . – Yakk