Here is what I am talking about
// some guy wrote this, used as a Policy with templates
struct MyWriter {
void write(std::vector const& dat
Why doesn't C++ do that?
I'm not sure what you're asking here. Could C++ be rewritten to allow this? Yes, but to what end?
Because MyWriter
and IWriter
are completely different classes, it is illegal in C++ to call a member of MyWriter
through an instance of IWriter
. The member pointers have completely different types. And just as a MyWriter*
is not convertible to a IWriter*
, neither is a void (MyWriter::*)(const std::vector
convertible to a void (IWriter::*)(const std::vector
.
The rules of C++ don't change just because there could be a third class that combines the two. Neither class is a direct parent/child relative of one another. Therefore, they are treated as entirely distinct classes.
Remember: member functions always take an additional parameter: a this
pointer to the object that they point to. You cannot call void (MyWriter::*)(const std::vector
on an IWriter*
. The third class can have a method that casts itself into the proper base class, but it must actually have this method. So either you or the C++ compiler must create it. The rules of C++ require this.
Consider what would have to happen to make this work without a derived-class method.
A function gets an IWriter*
. The user calls the write
member of it, using nothing more than the IWriter*
pointer. So... exactly how can the compiler generate the code to call MyWriter::writer
? Remember: MyWriter::writer
needs a MyWriter
instance. And there is no relationship between IWriter
and MyWriter
.
So how exactly could the compiler do the type coercion locally? The compiler would have to check the virtual function to see if the actual function to be called takes IWriter
or some other type. If it takes another type, it would have to convert the pointer to its true type, then do another conversion to the type needed by the virtual function. After doing all of that, it would then be able to make the call.
All of this overhead would affect every virtual call. All of them would have to at least check to see if the actual function to be call. Every call will also have to generate the code to do the type conversions, just in case.
Every virtual function call would have a "get type" and conditional branch in it. Even if it is never possible to trigger that branch. So you would be paying for something regardless of whether you use it or not. That's not the C++ way.
Even worse, a straight v-table implementation of virtual calls is no longer possible. The fastest method of doing virtual dispatch would not be a conforming implementation. The C++ committee is not going to make any change that would make such implementations impossible.
Again, to what end? Just so that you don't have to write a simple forwarding function?