Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
October 08, 2013 auto attribute for interface functions | ||||
---|---|---|---|---|
| ||||
``` interface I { //auto foo(int i); //forbidden auto bar(T)(T i); //Error: function a.I.bar!(int).bar has no function body with return type inference } class A:I { int foo(int i) { return i; } T bar(T)(T i) { return i; } } class B:I { int foo(int i) { return i; } string bar(T)(T i) { import std.conv; return to!string(i); } } void main() { import std.stdio; //void fun(I i) //{ // writeln(i.bar(1)); //Error (see above) //} auto a = new A(); auto b = new B(); writeln(a.foo(2)); //works fine writeln(a.foo(3)); //works fine //fun(a); //Error (see above) //fun(b); //Error (see above) } ``` Does class A or class B implement I ? |
October 08, 2013 Re: auto attribute for interface functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roman | On Tuesday, 8 October 2013 at 13:40:47 UTC, Roman wrote:
> ```
> interface I
> {
> //auto foo(int i); //forbidden
>
> auto bar(T)(T i); //Error: function a.I.bar!(int).bar has no function body with return type inference
> }
>
> class A:I
> {
> int foo(int i)
> {
> return i;
> }
>
> T bar(T)(T i)
> {
> return i;
> }
> }
>
> class B:I
> {
> int foo(int i)
> {
> return i;
> }
>
> string bar(T)(T i)
> {
> import std.conv;
> return to!string(i);
> }
> }
>
> void main()
> {
> import std.stdio;
>
> //void fun(I i)
> //{
> // writeln(i.bar(1)); //Error (see above)
> //}
>
> auto a = new A();
> auto b = new B();
>
> writeln(a.foo(2)); //works fine
> writeln(a.foo(3)); //works fine
>
> //fun(a); //Error (see above)
> //fun(b); //Error (see above)
> }
> ```
> Does class A or class B implement I ?
Seems, I've tried to use virtual templates manner. But it doesn't realizes in D yet
|
October 08, 2013 Re: auto attribute for interface functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roman | On Tuesday, October 08, 2013 17:26:04 Roman wrote:
> Seems, I've tried to use virtual templates manner. But it doesn't realizes in D yet
Fundamentally, making templates virtual doesn't really work. If it's possible, it would be quite difficult, and AFAIK, it's impossible. Templated functions aren't actual functions - they're templates for functions. The code isn't generated until the template is instantiated, which pretty much only happens when the function is called. And it's unknown when the template is written what types are going to be used with it. In fact, since the template could be in a library, and code could use that library well after the library has been written, it's quite possible for the types that will be used with the template to not even have been conceived yet when the template is written. Contrast this with virtual functions which must sit in the virtual table of a class. They have to be known when the class is compiled. As such, there is a fundamental conflict between how templates work and how virtual functions work. They just don't mix.
- Jonathan M Davis
|
October 09, 2013 Re: auto attribute for interface functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roman | On Tuesday, 8 October 2013 at 13:40:47 UTC, Roman wrote: > ``` > interface I > { > //auto foo(int i); //forbidden > > auto bar(T)(T i); //Error: function a.I.bar!(int).bar has no function body with return type inference > } Basically the error on the template answers your statement, bar has no implementation so the compiler can't decide what the return type should be. Similarly a template can't be overridden since it doesn't exist until you use it. What you can do is make final templates which aren't ever inherited but can forward to functions which can be inherited[1]. 1. http://3d.benjamin-thaut.de/?p=94 |
October 09, 2013 Re: auto attribute for interface functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | > In fact, since the template could be in a library, and code could use that library well after the library has been written... > As such, there is a fundamental conflict between how templates work and how virtual functions work. They just don't mix. Seems, the same problem doesn't allow auto attribute to virtual functions, because technically ,I think, possible get type from implemented functions, and if code trying to use return type not appropriate manner then throw runtime exception. Like this: ``` interface I { auto foo(int i); } class A:I { string foo(int i) { return to!string(i); } } void fun(I instance) { auto a = instance.foo(1); // or even // string a = instance.foo(1); writeln(a[0..$/2]); writeln(a*5); //here will thrown exception } ``` > What you can do is make final templates which aren't ever inherited but can forward to functions which can be inherited That looks intresting, but little different from using virtual functions. I think it is mix interfaces and abstract classes. |
October 09, 2013 Re: auto attribute for interface functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roman | On Wednesday, October 09, 2013 16:13:48 Roman wrote:
> > In fact, since the template could be in a library, and code
> > could use that library well after the library has been
> > written...
> > As such, there is a fundamental conflict between how templates
> > work and how virtual functions work. They just don't mix.
>
> Seems, the same problem doesn't allow auto attribute to virtual functions, because technically ,I think, possible get type from implemented functions, and if code trying to use return type not appropriate manner then throw runtime exception.
auto works fine as long as the body is there, since all auto means is that the type is inferred when the function is compiled. However, anything that overrides that function must return either the same type or a covariant type. So, using auto with virtual functions will work if you're returning the right type, but it's probably better to just give the explicit type.
- Jonathan M Davis
|
Copyright © 1999-2021 by the D Language Foundation