Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 08, 2010 Re: dmd 1.057 and 2.041 release | ||||
---|---|---|---|---|
| ||||
> 2) What's the best way to translate this to the new operator regime? > > T foo(T)(T s) if (__traits(hasMember, T, "opAdd")) { > return s + s; > } I have not found a good solution yet. This solution looks buggy (also because fixed-sized arrays have a buggy .init): import std.stdio: writeln; struct Foo { int x; this(int xx) { this.x = xx; } Foo opBinary(string s:"+")(Foo other) { return Foo(this.x * other.x); } } T foo(T)(T s) if (__traits(compiles, {return T.init + T.init;})) { return s + s; // line 14 } void main() { auto f1 = Foo(2); auto f2 = Foo(3); writeln(f1 + f2); writeln(foo(f1)); int[2] a = [1, 2]; writeln(typeid(typeof(a.init))); // prints: int writeln(foo(a)); // test.d(14): Error: Array operation s + s not implemented } Bye, bearophile |
March 08, 2010 Re: dmd 1.057 and 2.041 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 08/03/10 22:03, bearophile wrote: >> 2) What's the best way to translate this to the new operator regime? >> >> T foo(T)(T s) if (__traits(hasMember, T, "opAdd")) { >> return s + s; >> } > > I have not found a good solution yet. This solution looks buggy (also because fixed-sized arrays have a buggy .init): -snip- > T foo(T)(T s) if (__traits(compiles, {return T.init + T.init;})) { > return s + s; // line 14 > } Untested, will the following do what you need? ---- T foo(T)(T s) if (__traits(compiles, {return s + s;})) { return s + s; } ---- Seems like you may as well test if you can add what you're passed rather than the initial value for the type. |
March 08, 2010 Re: dmd 1.057 and 2.041 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert Clipsham | Robert Clipsham wrote:
> On 08/03/10 22:03, bearophile wrote:
>>> 2) What's the best way to translate this to the new operator regime?
>>>
>>> T foo(T)(T s) if (__traits(hasMember, T, "opAdd")) {
>>> return s + s;
>>> }
>>
>> I have not found a good solution yet. This solution looks buggy (also because fixed-sized arrays have a buggy .init):
> -snip-
>> T foo(T)(T s) if (__traits(compiles, {return T.init + T.init;})) {
>> return s + s; // line 14
>> }
>
> Untested, will the following do what you need?
>
> ----
> T foo(T)(T s) if (__traits(compiles, {return s + s;})) {
> return s + s;
> }
> ----
>
> Seems like you may as well test if you can add what you're passed rather than the initial value for the type.
What I usually do is:
T foo(T)(T s) if (is(typeof(s + s))) {
}
Andrei
|
March 08, 2010 Re: dmd 1.057 and 2.041 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert Clipsham | Robert Clipsham: > Untested, will the following do what you need? > ---- > T foo(T)(T s) if (__traits(compiles, {return s + s;})) { > return s + s; > } > ---- > Seems like you may as well test if you can add what you're passed rather than the initial value for the type. Oh, nice, I didn't remember you can also use values there and not just types. It becomes like this then: import std.stdio: writeln; struct Foo { int x; this(int xx) { this.x = xx; } Foo opBinary(string s:"+")(Foo other) { return Foo(this.x * other.x); } } T foo(T)(T s) if (__traits(compiles, {return s + s;})) { return s + s; // line 14 } void main() { auto f1 = Foo(2); auto f2 = Foo(3); writeln(f1 + f2); writeln(foo(f1)); int[2] a = [1, 2]; writeln(typeid(typeof(a.init))); // prints: int writeln(foo(a)); // test.d(14): Error: Array operation s + s not implemented } But now I don't know what's happening, because that trait correctly returns false, but the compiler generates a compile error at line 14 still. I think there's a new bug. Bye, bearophile |
March 08, 2010 Re: dmd 1.057 and 2.041 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > But now I don't know what's happening, because that trait correctly returns false, but the compiler generates a compile error at line 14 still. I think there's a new bug. I have added a bug: http://d.puremagic.com/issues/show_bug.cgi?id=3903 Bye, bearophile |
March 08, 2010 Re: dmd 1.057 and 2.041 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Andrei Alexandrescu:
> What I usually do is:
> T foo(T)(T s) if (is(typeof(s + s))) {
> }
Nice, thank you, I'll use that.
(That solution too presents the bug 3903)
Bye,
bearophile
|
March 08, 2010 Re: dmd 1.057 and 2.041 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 08/03/10 22:53, Andrei Alexandrescu wrote:
> What I usually do is:
>
> T foo(T)(T s) if (is(typeof(s + s))) {
> }
>
> Andrei
That's far nicer, I keep forgetting about is(typeof()), thanks :)
|
March 08, 2010 Re: dmd 1.057 and 2.041 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile Attachments:
| > writeln(typeid(typeof(a.init))); // prints: int > ?! You mean typeof(a) != typeof((typeof(a)).init) ?! Ugh... I thought (int[2]).init was [0,0] and in general (T[n]).init was [(T.init) n times] > writeln(foo(a)); // test.d(14): Error: Array operation s + s not > implemented > } > > > But now I don't know what's happening, because that trait correctly returns false, but the compiler generates a compile error at line 14 still. I think there's a new bug I think your bug is this discrepancy between init's type and the original type. That needs a bug report by itself; in a template constraint, any value is at its type .init value, not its runtype value (obvious in retrospect) In your example {return s+s;} becomes {return 0+0;}, since the compiler wrongly infer (int[2]).init to be 0, a regular int. And your __traits return true: auto bar(T)(T t) { return __traits(compiles, {return t+t;});} int[2] a; writeln(bar(a)); // true! Philippe |
March 08, 2010 Re: dmd 1.057 and 2.041 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert Clipsham | Robert Clipsham wrote:
> On 08/03/10 22:53, Andrei Alexandrescu wrote:
>> What I usually do is:
>>
>> T foo(T)(T s) if (is(typeof(s + s))) {
>> }
>>
>> Andrei
>
> That's far nicer, I keep forgetting about is(typeof()), thanks :)
It'll be hard to forget once TDPL will be out there, the idiom is present in several places.
Man I can't wait for that book to be out.
Andrei
|
March 08, 2010 Re: dmd 1.057 and 2.041 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | Philippe Sigaud: > > writeln(typeid(typeof(a.init))); // prints: int > > > > ?! You mean typeof(a) != typeof((typeof(a)).init) ?! > > Ugh... I thought (int[2]).init was [0,0] and in general (T[n]).init was > [(T.init) n times] http://d.puremagic.com/issues/show_bug.cgi?id=3826 Bye, bearophile |
Copyright © 1999-2021 by the D Language Foundation