Overloading the C ++ template class virtual function

Below is the code to recreate the problem I am facing. Base class is a template class with the virtual function foo . foo has a default implementation that adds the arguments passed.

SimpleDerived comes from Base , specializing in std::string . SimpleDerived overloads the virtual function Base<T>::foo() . This class compiles fine and its outputs foo , as expected when called in main .

 #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 comes from Base , specializing in a custom SimpleObject structure. ComplexDerived overload foo . However, this is the root of the problem. If I try to compile this, I get:

 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' 

Obviously, there is SimpleObject "+" operator for SimpleObject . But here is my confusion .. the compiler is invited to implement Base<SimpleObject>::foo , because this is what ComplexDerived inherits. However, I never use or call Base<SimpleObject>::foo . So should the compiler try to generate this base class function?

+6
source share
1 answer

Clause 14.7.1 / 10 of the C ++ 11 Standard states:

An implementation should not implicitly create a function template, a member template, a non-virtual member member, a member class, or a static data member of a class template that does not require instantiation. It is not indicated whether the implementation implements the virtual member function of the class template implicitly, if the virtual member function is not created otherwise. [...]

In other words, the behavior in this case is implementation-specific.

Although, theoretically, the compiler could understand that the call to the implementation of the base class foo() would never be called (since the call to the function does not occur through a link or pointer) and avoid creating it, this behavior is not provided for in the Standard.

+9
source

Source: https://habr.com/ru/post/947344/


All Articles