Assuming I had two classes, the first one for writing primitive types (bool, int, float, etc.) and the second one extending the first to also write complex types:
struct Writer {
virtual void Write(int value) = 0;
};
struct ComplexWriter : public Writer {
template <typename TValue> void Write(const TValue &value) {
boost::any any(value);
Write(any);
}
//virtual void Write(int value) = 0; // see question below
virtual void Write(const boost::any &any) = 0;
};
The idea is that if someone calls myWriter.Write(someIntValue);, the int overload will receive priority over the templated method.
Instead, my compiler (Visual C++ 11.0 RC) always picks the template method. The following code snippet, for example, will print Wrote any to the console:
struct ComplexWriterImpl : public ComplexWriter {
virtual void Write(int value) { std::cout << "Wrote an int"; }
virtual void Write(const boost::any &any) { std::cout << "Wrote any"; }
};
void TestWriter(ComplexWriter &writer) {
int x = 0;
writer.Write(x);
}
int main() {
ComplexWriterImpl writer;
TestWriter(writer);
}
The behavior suddenly changes when I declare the Write(int) method in the ComplexWriter class as well (see commented out line in the first snippet). It then prints Wrote an int to the console.
Is this how my compiler ought to behave? Does the C++ standard explicitly say that only overloads defined in the same class (and not a base class) shall be prioritized over a templated method?
The problem is that at the point you’re calling
writer.Write(x)the compiler sees aComplexWriternot aComplexWriterImpl, so it is only aware of the functions defined inComplexWriter– the template function and theboost::anyfunction.ComplexWriterdoes not contain any virtual functions that accept anint, so it has no way to call through to the int overload defined inComplexWriterImplWhen you add in the virtual overload to the
ComplexWriterclass, then the compiler becomes aware that there is an integer overload in theComplexWriterclass and therefore calls through to it’s implementation inComplexWriterImplEDIT: Now that you’ve edited in the inheritance between ComplexWriter & Writer, I’ve got a more complete explanation for you:
When you create a subclass and define a function in it then all of the functions of that name in the base class will be hidden, regardless of their argument types.
You can get around this with the using keyword I believe:
For more details see this FAQ entry: http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9
EDIT 2: Just to confirm that this does indeed solve your problem: http://ideone.com/LRb5a