Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
July 18, 2018 Why does templated interface function return something different than final function? | ||||
---|---|---|---|---|
| ||||
Why is the interface templated function not also returning the class C toString return value "in C"?? interface iface { void toString(scope void delegate(const(char)[]) sink) const; final string convert() inout { import std.conv; // assert(std.conv.to!string(this) == "in C"); // fails! return std.conv.to!string(this); } final string convert2() const { import std.conv; assert(std.conv.to!string(this) == "in C"); return std.conv.to!string(this); } } class C : iface { void toString(scope void delegate(const(char)[]) sink) const { sink("in C"); } } void main () { iface i = new C(); import std.stdio; writeln(i.convert); // "app.C" writeln(i.convert2()); // "in C" } It seems like `inout` triggers some odd behaviour?? |
July 18, 2018 Re: Why does templated interface function return something different than final function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timoses | On Wednesday, 18 July 2018 at 11:09:12 UTC, Timoses wrote:
> Why is the interface templated function not also returning the class C toString return value "in C"??
>
> interface iface
> {
> void toString(scope void delegate(const(char)[]) sink) const;
>
> final string convert() inout
> {
> import std.conv;
> // assert(std.conv.to!string(this) == "in C"); // fails!
> return std.conv.to!string(this);
> }
>
> final string convert2() const
> {
> import std.conv;
> assert(std.conv.to!string(this) == "in C");
> return std.conv.to!string(this);
> }
> }
>
> class C : iface
> {
> void toString(scope void delegate(const(char)[]) sink) const
> {
> sink("in C");
> }
> }
>
> void main ()
> {
> iface i = new C();
> import std.stdio;
> writeln(i.convert); // "app.C"
> writeln(i.convert2()); // "in C"
> }
>
> It seems like `inout` triggers some odd behaviour??
Sorry, I experimented a bit and forgot to change the topic to something more fitting, e.g.
"Why does inout struct function return different results?"
|
August 02, 2018 Re: Why does templated interface function return something different than final function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timoses | On 7/18/18 7:09 AM, Timoses wrote:
> Why is the interface templated function not also returning the class C toString return value "in C"??
>
> interface iface
> {
> void toString(scope void delegate(const(char)[]) sink) const;
>
> final string convert() inout
> {
> import std.conv;
> // assert(std.conv.to!string(this) == "in C"); // fails!
> return std.conv.to!string(this);
> }
>
> final string convert2() const
> {
> import std.conv;
> assert(std.conv.to!string(this) == "in C");
> return std.conv.to!string(this);
> }
> }
>
> class C : iface
> {
> void toString(scope void delegate(const(char)[]) sink) const
> {
> sink("in C");
> }
> }
>
> void main ()
> {
> iface i = new C();
> import std.stdio;
> writeln(i.convert); // "app.C"
> writeln(i.convert2()); // "in C"
> }
>
> It seems like `inout` triggers some odd behaviour??
Looking at the AST, it appears that toImpl doesn't recognize what inout(iface) is:
toImpl!(string, inout(iface))
{
@system string toImpl(ref inout(iface) value)
{
import std.array : appender;
import std.format : FormatSpec, formatValue;
Appender!string w = appender();
FormatSpec!char f = FormatSpec;
formatValue(w, value, f);
return w.data();
}
}
Vs. the nice neat call for const(iface)
toImpl!(string, const(iface))
{
@system string toImpl(const(iface) value)
{
return toStr(value);
}
}
Note the ref there, too. This means it can't cast to const. I wonder if that's an issue.
-Steve
|
August 06, 2018 Re: Why does templated interface function return something different than final function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Thursday, 2 August 2018 at 20:35:57 UTC, Steven Schveighoffer wrote:
>
> Looking at the AST, it appears that toImpl doesn't recognize what inout(iface) is:
>
> toImpl!(string, inout(iface))
> {
> @system string toImpl(ref inout(iface) value)
> {
> import std.array : appender;
> import std.format : FormatSpec, formatValue;
> Appender!string w = appender();
> FormatSpec!char f = FormatSpec;
> formatValue(w, value, f);
> return w.data();
> }
>
> }
>
> Vs. the nice neat call for const(iface)
>
> toImpl!(string, const(iface))
> {
> @system string toImpl(const(iface) value)
> {
> return toStr(value);
> }
>
> }
>
> Note the ref there, too. This means it can't cast to const. I wonder if that's an issue.
>
> -Steve
Thanks for the insight. To me it sounds like std.conv `toImpl` doesn't properly handle inout types in this case.
|
August 08, 2018 Re: Why does templated interface function return something different than final function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timoses | On Monday, 6 August 2018 at 14:27:01 UTC, Timoses wrote: > On Thursday, 2 August 2018 at 20:35:57 UTC, Steven Schveighoffer wrote: >> >> Looking at the AST, it appears that toImpl doesn't recognize what inout(iface) is: >> >> toImpl!(string, inout(iface)) >> { >> @system string toImpl(ref inout(iface) value) >> { >> import std.array : appender; >> import std.format : FormatSpec, formatValue; >> Appender!string w = appender(); >> FormatSpec!char f = FormatSpec; >> formatValue(w, value, f); >> return w.data(); >> } >> >> } >> >> Vs. the nice neat call for const(iface) >> >> toImpl!(string, const(iface)) >> { >> @system string toImpl(const(iface) value) >> { >> return toStr(value); >> } >> >> } >> >> Note the ref there, too. This means it can't cast to const. I wonder if that's an issue. >> >> -Steve > > Thanks for the insight. To me it sounds like std.conv `toImpl` doesn't properly handle inout types in this case. Well, my "workaround" now is to simply cast the inout type to const before passing to std.conv.to ... I've experimented a bit more and compiled it a bit together. import std.stdio; import std.conv : to; interface I { void toString(scope void delegate(const(char)[]) sink) const; final void printI() { writeln(this.to!string); // this is class A } final void printIinout() inout { writeln(this.to!string); // app.A } } class A : I { void print() { writeln(this.to!string); // this is class A } // Compilation error // std\format.d(3890,13): Error: template instance `std.format.formatObject!(Appender!string, inout(A), char)` does not match template declaration `formatObject(Writer, T, Char)(ref Writer w, ref T val, ref const FormatSpec!Char f) if (hasToString!(T, Char))` /*void printinout() inout { writeln(this.to!string); }*/ override void toString(scope void delegate(const(char)[]) sink) const { sink("this is class A"); } } unittest { I i = new A(); i.printI(); i.printIinout(); A a = new A(); a.print(); //a.printinout(); } It seems inconsistent to me. What do you think? Should I open a bug report for this? Also the compilation error should not occur, should it? |
Copyright © 1999-2021 by the D Language Foundation