2016-06-15 3 views
1

상속 과부하 템플릿 연산자와 A<int>의 운영자가 base에서 운영자를 무색하게하는 이유상속 및

가 이해가 안 과부하 템플릿 연산자. 결국 서명이 다릅니다.

#include <iostream> 

struct base { 
    template <typename U> 
    void operator()(U&& x) { std::cout << "base" << std::endl; } 
}; 

template <typename T> 
struct A: public base { }; 

template <> 
struct A<int>: public base { 
    void operator()() { std::cout << "A<int>" << std::endl; } // line 1 
}; 

int main() 
{ 
    A<double>()(1); 
    A<int>()(1); // line 2 
    A<int>()(); // line 3 
} 

줄 1이 있으면 줄 2가 컴파일되지 않습니다.

라인 1이 제거되면 (분명히) 라인 3이 컴파일되지 않습니다.

베이스에서 A로 연산자 템플릿을 복사하면 모든 것이 작동합니다.

base 
base 
A<int> 
+1

* 이름 숨기기 *라고합니다. 예 : http://stackoverflow.com/questions/1628768/why-does-an-overridden-function-in-the-derived-class-hide-other-overloads-of-the –

+0

문제를 해결하려면 'using base :: operator();'클래스 A에서 접근성은 선언을 삽입하는 위치에 따라 다르며 부모의 접근성을 변경할 수 있다는 점에 유의하십시오 (예 : 공용으로 사용하여 보호 된 함수를 public으로 만드는 것). 섹션). – Aconcagua

+0

그리고 이런 식으로 하나의 함수를 "숨김 해제"할 수는 없다는 것을 알아 두십시오 - 모든 오버로드 또는 없음 (예외 : 부모에 주어진 이름을 가진 함수가 하나뿐입니다 ...). – Aconcagua

답변

2

파생 된 클래스에서 운전자의 선언은 기본 클래스 이름을 숨기고 :

는 I 출력이 될 것으로 기대.

template <> 
struct A<int>: public base { 
    using base::operator(); 
    void operator()() { std::cout << "A<int>" << std::endl; } 
}; 

를 그리고 둘 다 컴파일 :
문제 해결 에, 그것은 using declaration의 문제이다.

+0

고마워, 그거야. 다중 선언 상 문제를 예방하기 위해 '사용 선언'의 요점은 의무적인가? 표준이 '선언 사용'이 없다면 첫 번째로 나열된 부모 클래스의 함수가 사용된다는 것을 표준이 명시한다면 문제가 있을까요? – SU3

+0

질문에 대한 답변으로 http://stackoverflow.com/a/1629074/2640636 감사합니다. @Alan Stokes – SU3