www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - toString OutputWriter method not calling derived class

reply cc <cc nevernet.com> writes:
When defining a toString(W)(ref W writer) function on a base 
class and derived class, only the version on the base class is 
called when formatting into a string.  Is this intended behavior?

import std.format;
import std.range.primitives;
class Foo {
	string test() {
		return "Foo?";
	}
	void toString(W)(ref W writer) if (isOutputRange!(W, char)) {
		put(writer, "<FOO>");
	}
}
class Bar : Foo {
	override string test() {
		return "Bar?";
	}
	void toString(W)(ref W writer) if (isOutputRange!(W, char)) {
		put(writer, "<BAR>");
	}
}
Foo[] list = [new Foo(), new Bar()];
foreach(i, item; list) {
	writefln("%d: %s (%s)", i, item, item.test());
}


Result:
0: <FOO> (Foo?)
1: <FOO> (Bar?)
May 25 2018
parent rikki cattermole <rikki cattermole.co.nz> writes:
On 25/05/2018 9:21 PM, cc wrote:
 When defining a toString(W)(ref W writer) function on a base class and 
 derived class, only the version on the base class is called when 
 formatting into a string.  Is this intended behavior?
 
 import std.format;
 import std.range.primitives;
 class Foo {
      string test() {
          return "Foo?";
      }
      void toString(W)(ref W writer) if (isOutputRange!(W, char)) {
          put(writer, "<FOO>");
      }
 }
 class Bar : Foo {
      override string test() {
          return "Bar?";
      }
      void toString(W)(ref W writer) if (isOutputRange!(W, char)) {
          put(writer, "<BAR>");
      }
 }
 Foo[] list = [new Foo(), new Bar()];
 foreach(i, item; list) {
      writefln("%d: %s (%s)", i, item, item.test());
 }
 
 
 Result:
 0: <FOO> (Foo?)
 1: <FOO> (Bar?)
 
Yes, because templates are not virtual.
May 25 2018