다음은 내가 가지고있는 문제를 재현하는 코드입니다. Base
클래스는 가상 함수가 foo
인 템플릿 클래스입니다. foo
에는 전달 된 인수를 추가하는 기본 구현이 있습니다.C++ 템플릿 클래스 가상 함수 오버로드
SimpleDerived
은 Base
에서 파생되며 std::string
으로 전문화됩니다. SimpleDerived
은 가상 Base<T>::foo()
기능을 오버로드합니다. 이 클래스는 main
에서 호출 될 때 잘 컴파일되고 foo
출력을 예상대로 컴파일합니다.
#include <iostream>
template<class T>
struct Base
{
virtual void foo(T val)
{
T local = val + val; // THE OFFENDING LINE OF CODE
std::cout << "Base" << std::endl;
}
};
struct SimpleDerived : public Base<std::string>
{
virtual void foo(std::string val)
{
std::cout << "SimpleDerived" << std::endl;
}
};
struct SimpleObject
{
int value;
};
struct ComplexDerived : public Base<SimpleObject>
{
virtual void foo(SimpleObject val)
{
std::cout << "ComplexDerived" << std::endl;
}
};
int main(void)
{
Base<int> base;
base.foo(2);
SimpleDerived simpleDerived;
simpleDerived.foo("hello world");
SimpleObject object;
ComplexDerived complexDerived;
complexDerived.foo(object);
return 0;
}
ComplexDerived
사용자 정의 구조체 SimpleObject
와 함께 전문 Base
에서 유래. ComplexDerived
은 foo
에도 오버로드됩니다. 그러나 이것이 문제의 근원입니다. 나는 이것을 컴파일하려고하면 내가 얻을 :
quicktest.cpp: In member function ‘void Base<T>::foo(T) [with T = SimpleObject]’:
quicktest.cpp:47:1: instantiated from here
quicktest.cpp:8:19: error: no match for ‘operator+’ in ‘val + val’
을 분명히 어떤 연산자는 "+"SimpleObject
을 위해 존재하지 않는다. 하지만 여기에 내 혼란이있다. 컴파일러는 Base<SimpleObject>::foo
을 구현해야한다. 왜냐하면 이것이 ComplexDerived
에서 상속받은 것이기 때문이다. 그러나 절대로 Base<SimpleObject>::foo
을 사용하거나 전화하지 않습니다. 그래서 컴파일러는이 기본 클래스 함수를 생성하려고합니까? 는 C++ 11 표준 지정의
컴파일러가 기본 클래스에서 가상 함수를 인스턴스화하려고 할 때 대답을 확인하는 것처럼 보일 수도 있기 때문에 템플릿 순수화를 사용하여 문제를 해결할 수 있습니다. – kloffy