Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <p>Why doesn't C++ do that?</p> </blockquote> <p>I'm not sure what you're asking here. <em>Could</em> C++ be rewritten to allow this? Yes, but to what end?</p> <p>Because <code>MyWriter</code> and <code>IWriter</code> are completely different classes, it is illegal in C++ to call a member of <code>MyWriter</code> through an instance of <code>IWriter</code>. The member pointers have completely different types. And just as a <code>MyWriter*</code> is not convertible to a <code>IWriter*</code>, neither is a <code>void (MyWriter::*)(const std::vector&lt;char&gt;&amp;)</code> convertible to a <code>void (IWriter::*)(const std::vector&lt;char&gt;&amp;)</code>.</p> <p>The rules of C++ don't change just because there <em>could</em> 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.</p> <p>Remember: member functions always take an additional parameter: a <code>this</code> pointer to the object that they point to. You cannot call <code>void (MyWriter::*)(const std::vector&lt;char&gt;&amp;)</code> on an <code>IWriter*</code>. The third class can have a method that casts itself into the proper base class, but it must actually <em>have this method</em>. So either you or the C++ compiler must create it. The rules of C++ require this.</p> <p>Consider what would have to happen to make this work without a derived-class method.</p> <p>A function gets an <code>IWriter*</code>. The user calls the <code>write</code> member of it, using nothing more than the <code>IWriter*</code> pointer. So... exactly how can the compiler generate the code to call <code>MyWriter::writer</code>? Remember: <code>MyWriter::writer</code> <strong>needs</strong> a <code>MyWriter</code> instance. And there is no relationship between <code>IWriter</code> and <code>MyWriter</code>.</p> <p>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 <code>IWriter</code> 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.</p> <p>All of this overhead would affect <em>every</em> 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.</p> <p>Every virtual function call would have a "get type" and conditional branch in it. Even if it is <em>never</em> 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.</p> <p>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 <strong><em>not</em></strong> going to make any change that would make such implementations impossible.</p> <p>Again, to what end? Just so that you don't have to write a simple forwarding function?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. COI'm not literally asking for the ability to directly call `MyWriter::write` by calling `IWriter::write`. I just don't want to put a function definition into `MyOwnClass` that just forwards to `MyWriter::write`. Can the compiler not do that for me? All I wonder about is: The resulting object could be set up such that a call to `IWriter::write` *ends up* calling `MyWriter::write`. There can be trampolines and whatnot in between them (whatever needed to make it work) that eventually do the final call to `MyWriter::write`.
      singulars
    2. COIn this case, the language too allows the cross case of `A` to `B` even though neither class " is a direct parent/child relative of one another". But objects of both classes appear as subobjects of a single complete object: `struct A { virtual ~A() {}}; struct B { virtual ~B() {} void f() {}}; struct C : A, B {}; int main() { A *a = new C; dynamic_cast<B*>(a)->f(); }`. In my case too, both classes appear as base classes of a single derived class.
      singulars
    3. CO@Johannes: "Can the compiler not do that for me?" Yes, it could. But it wouldn't do it implicitly, so you'd still need *some* syntax there to tell the compiler to do it. And since that syntax needs a function signature, as well as the name (and likely the signature) of the function to call... it would really just be a small bit of syntactic sugar for writing the forwarding function yourself. Feel free to propose this to the C++1y standardization committee. I wouldn't expect it to gain much traction though, considering how much of a corner case it is.
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload