Consider following example
#include <iostream>
struct PureVirtual {
virtual void Function() = 0;
};
struct FunctionImpl {
virtual void Function() {
std::cout << "FunctionImpl::Function()" << std::endl;
}
};
struct NonPureVirtual : public FunctionImpl, public PureVirtual {
using FunctionImpl::Function;
};
int main() {
NonPureVirtual c;
c.Function();
}
Compiler (GCC 4.9, Clang 3.5) exits with error
test.cpp:18:20: error: variable type 'NonPureVirtual' is an abstract class
NonPureVirtual c;
^
test.cpp:4:18: note: unimplemented pure virtual method 'Function' in 'NonPureVirtual'
virtual void Function() = 0;
^
But when I don't derive form PureVirtual everything is OK. This is weird because Standard 10.4.4 says
A class is abstract if it contains or inherits at least one pure virtual function for which the final overrider is pure virtual.
They are not saying anything about what the final overrider is but I suppose it should be FunctionImpl::Function() especially when I made it available through using directive. So why is still NonPureVirtual abstract class and how can I fix this.
FunctionImpl::FunctionandPureVirtual::Functionare different functions from different classes.Their respective types are
void (FunctionImpl::*)()andvoid (PureVirtual::*)().Since
PureVirtualandFunctionImplare unrelated classes, these function types are unrelated.They happen to have the same name and the same parameters and return type, but since they're different, the
using FunctionImpl::Functionline doesn't make that function an override of the one inPureVirtual.And if you declared a variable of type
void (PureVirtual::*)(), you wouldn't be able to assignFunctionImpl::Functionto it.In other words, the final override of
PureVirtual::Functionis the original one inPureVirtual, which is pure virtual.For making what you want possible, Matthieu M.'s answer (using a forwarding call) is the way to go, it seems.