Why can't a method be virtual AND static at the same time?

Frustrated c1514843 at drdrb.com
Wed Jan 29 07:21:53 PST 2014


On Wednesday, 29 January 2014 at 13:30:54 UTC, Martin Cejp wrote:
> This is a feature I've always missed in C++. Consider the code
> below:
>
> import std.stdio;
>
> interface Logger {
> 	void print(string msg);
> }
>
> class ConsoleLogger : Logger {
> 	static override void print(string msg) {
> 		writeln(msg);
> 	}
> }
>
> void main() {
> 	Logger logger = new ConsoleLogger;
> 	
> 	ConsoleLogger.print("Hello, World!");
> }
>
> Such definition of ConsoleLogger fails to compile. I don't see
> any drawbacks to allowing this though, except the compiler would
> probably have to generate 2 methods internally.
> The way it is now, you have to either define each method twice 
> or
> always create an instance.
> Or am I missing an obvious solution?

No, you are mixing concepts. Logger.print is a function that uses
a vtable and takes a hidden parameter this.

ConsoleLogger.print is a regular function that is not in a
vtable(because it is static) and does not take a hidden
parameter(again, because it is static).

So, when you do ConsoleLogger.print how the heck would the
compiler know which one you meant to use? While this might have a
solution, in some cases in general a virtual method REQUIRES a
virtual table and by using the keyword static on a function you
are saying it is not part of the virtual table.



Basically what you want is polymorphism here. Your two print
functions are different.


module main;

import std.stdio;

interface Logger {
	void print(string msg);
}

class ConsoleLogger : Logger {
	void print(string msg) { writeln(msg); }
	static void print2(string msg) { writeln(msg); }
          // Can we not rename print2 to print?
}

void main() {
	Logger logger = new ConsoleLogger;	
	ConsoleLogger.print2("Hello, World!");
}


works because you used a different name for print(print2) so
there is no confusion.

One could say that since you "access" print from the class(and
not the object) that the compiler should use the static method
instead of the virtual.

This is actually different than saying print is both static and
non-static(virtual), which is impossible.

This all has to do with using the the same name of different
things just like overriding methods do(they are actually
different methods but use the same name because they have
different definitions and generally can be deduced). It may be
possible to do the same here. I don't know if there are any
pitfalls. You would still need to implement the interface method
print though, regardless.

The real issue comes from cases like this though:

module main;

import std.stdio;

interface Logger {
	void print(string msg);
}

class ConsoleLogger : Logger {
	void print(string msg) { writeln(msg); }
	static void print(string msg) { writeln(msg); }
          // assume this works
}

void main() {
	auto logger = new ConsoleLogger;	
	logger.print("Hello, World!");
}

Do you know the issue now? (Again, there might be ways around it
but current that is not how the compiler thinks)






More information about the Digitalmars-d mailing list