Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 26, 2013 Overload of ! operator | ||||
---|---|---|---|---|
| ||||
Is there a way to overload the ! operator? I can't seem to get it to work with the standard unaryOp method. I need this because I am making a wrapper for a C++ API that has ! overloaded. -Eric |
June 26, 2013 Re: Overload of ! operator | ||||
---|---|---|---|---|
| ||||
Posted in reply to Eric | Eric:
> Is there a way to overload the ! operator? I can't seem to get
> it to work with the standard unaryOp method. I need this because
> I am making a wrapper for a C++ API that has ! overloaded.
D is not a superset of C++ and I think there is no way to overload the ! alone. This is by design. But you can define a "bang" property method.
Maybe other people can give you a better answer.
Bye,
bearophile
|
June 26, 2013 Re: Overload of ! operator | ||||
---|---|---|---|---|
| ||||
Posted in reply to Eric | On Wednesday, June 26, 2013 04:50:44 Eric wrote:
> Is there a way to overload the ! operator? I can't seem to get it to work with the standard unaryOp method. I need this because I am making a wrapper for a C++ API that has ! overloaded.
TDPL does not list it as an overloadable operator, so it probably can't be overloaded (especially if you've tried it, and it doesn't work). But you should be able to simply have a wrapper function which is a normal function rather than an overloaded operator.
- Jonathan M Davis
|
June 26, 2013 Re: Overload of ! operator | ||||
---|---|---|---|---|
| ||||
Posted in reply to Eric | On Wednesday, 26 June 2013 at 02:50:51 UTC, Eric wrote: > > Is there a way to overload the ! operator? I can't seem to get > it to work with the standard unaryOp method. I need this because > I am making a wrapper for a C++ API that has ! overloaded. > > -Eric According to http://dlang.org/operatoroverloading.html#Cast, the following are rewritten: if (e) => if (e.opCast!(bool)) if (!e) => if (!e.opCast!(bool)) So perhaps you need to override opCast!(bool). |
June 26, 2013 Re: Overload of ! operator | ||||
---|---|---|---|---|
| ||||
Posted in reply to cal | On Wednesday, June 26, 2013 05:35:03 cal wrote:
> On Wednesday, 26 June 2013 at 02:50:51 UTC, Eric wrote:
> > Is there a way to overload the ! operator? I can't seem to get
> > it to work with the standard unaryOp method. I need this
> > because
> > I am making a wrapper for a C++ API that has ! overloaded.
> >
> > -Eric
>
> According to http://dlang.org/operatoroverloading.html#Cast, the following are rewritten:
>
> if (e) => if (e.opCast!(bool))
> if (!e) => if (!e.opCast!(bool))
>
> So perhaps you need to override opCast!(bool).
Yeah, that should work for the conditions in if, while, and for loops but won't work for anything else (_maybe_ ternary operators, but I'm not sure). So, if you need to be able to do !obj in the general case, that's not going to work, but if you only need it for conditions, then it would. And of course this all assumes that the C++ code is overloading ! to do something sane with bool rather than redefining it to mean something completely different.
- Jonathan M Davis
|
June 26, 2013 Re: Overload of ! operator | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 06/25/2013 09:05 PM, Jonathan M Davis wrote: > On Wednesday, June 26, 2013 05:35:03 cal wrote: >> On Wednesday, 26 June 2013 at 02:50:51 UTC, Eric wrote: >>> Is there a way to overload the ! operator? I can't seem to get >>> it to work with the standard unaryOp method. I need this >>> because >>> I am making a wrapper for a C++ API that has ! overloaded. >>> >>> -Eric >> >> According to http://dlang.org/operatoroverloading.html#Cast, the >> following are rewritten: >> >> if (e) => if (e.opCast!(bool)) >> if (!e) => if (!e.opCast!(bool)) >> >> So perhaps you need to override opCast!(bool). > > Yeah, that should work for the conditions in if, while, and for loops but > won't work for anything else (_maybe_ ternary operators, but I'm not sure). Works for ternary as well. The other option is 'alias this' but it is a little dangerous because bool is an arithmetic type. So, opCast would be better. import std.stdio; struct S { int i; bool truth() const { return i == 42; } alias truth this; } void foo(bool b) { writeln(b); } void main() { auto s = S(42); if (s){ } while (s) { break; } int i = s ? 4 : 5; foo(s); // What does it mean? writeln(s + 2); writeln(!s - 7); } > So, if you need to be able to do !obj in the general case, that's not going to > work It surprisingly works both with opCast and 'alias this'. Ali |
June 26, 2013 Re: Overload of ! operator | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Wednesday, 26 June 2013 at 04:16:30 UTC, Ali Çehreli wrote:
> On 06/25/2013 09:05 PM, Jonathan M Davis wrote:
>
> > On Wednesday, June 26, 2013 05:35:03 cal wrote:
> >> On Wednesday, 26 June 2013 at 02:50:51 UTC, Eric wrote:
> >>> Is there a way to overload the ! operator? I can't seem to
> get
> >>> it to work with the standard unaryOp method. I need this
> >>> because
> >>> I am making a wrapper for a C++ API that has ! overloaded.
> >>>
> >>> -Eric
> >>
> >> According to http://dlang.org/operatoroverloading.html#Cast,
> the
> >> following are rewritten:
> >>
> >> if (e) => if (e.opCast!(bool))
> >> if (!e) => if (!e.opCast!(bool))
> >>
> >> So perhaps you need to override opCast!(bool).
> >
> > Yeah, that should work for the conditions in if, while, and
> for loops but
> > won't work for anything else (_maybe_ ternary operators, but
> I'm not sure).
>
> Works for ternary as well.
>
> The other option is 'alias this' but it is a little dangerous because bool is an arithmetic type. So, opCast would be better.
>
> import std.stdio;
>
> struct S
> {
> int i;
>
> bool truth() const
> {
> return i == 42;
> }
>
> alias truth this;
> }
>
> void foo(bool b)
> {
> writeln(b);
> }
>
> void main()
> {
> auto s = S(42);
>
> if (s){
> }
>
> while (s) {
> break;
> }
>
> int i = s ? 4 : 5;
>
> foo(s);
>
> // What does it mean?
> writeln(s + 2);
> writeln(!s - 7);
> }
>
> > So, if you need to be able to do !obj in the general case,
> that's not going to
> > work
>
> It surprisingly works both with opCast and 'alias this'.
>
> Ali
Thanks for all the insignt. But I think I'm just going to fudge this one
with a "bang()" method...
Incidently, for this project I figured out an interesting use of alias.
The C++ classes I am wrapping have a lot of virtual methods with all primitive arguments. So I create an D-interface for them, and wrap the rest with C methods. The wrapper class then makes methods that call the C methods, and then aliases the interface reference to "this" so that the wrapper class instance points to both the C++ native methods as well as the C-wrapped methods.
-Eric
|
June 26, 2013 Re: Overload of ! operator | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Wednesday, 26 June 2013 at 04:06:05 UTC, Jonathan M Davis wrote:
> Yeah, that should work for the conditions in if, while, and for loops but
> won't work for anything else (_maybe_ ternary operators, but I'm not sure).
> So, if you need to be able to do !obj in the general case, that's not going to
> work
...
import std.stdio;
struct S {
int x;
bool opCast(T)() if (is(T == bool)) {
return x == 0;
}
}
void main() {
auto s = S(1);
auto b = !s;
writeln(b); // true
}
Is this not supposed to work?
|
June 26, 2013 Re: Overload of ! operator | ||||
---|---|---|---|---|
| ||||
Posted in reply to cal | On Wednesday, June 26, 2013 06:59:14 cal wrote:
> On Wednesday, 26 June 2013 at 04:06:05 UTC, Jonathan M Davis
>
> wrote:
> > Yeah, that should work for the conditions in if, while, and for
> > loops but
> > won't work for anything else (_maybe_ ternary operators, but
> > I'm not sure).
> > So, if you need to be able to do !obj in the general case,
> > that's not going to
> > work
>
> ...
>
> import std.stdio;
>
> struct S {
> int x;
> bool opCast(T)() if (is(T == bool)) {
> return x == 0;
> }
> }
>
> void main() {
> auto s = S(1);
> auto b = !s;
> writeln(b); // true
> }
>
> Is this not supposed to work?
No, it's not. That would require an implicit cast (which requires using alias this). opCast gives you an explicit cast only. Where that becomes confusing is the fact that the compiler inserts explicitly casts to bool in conditions for if statements, loops, and the ternary operator. e.g.
if(foo) {...}
becomes
if(cast(bool)foo) {...}
So, if you've overloaded opCast to bool, then it'll get used in the conditions for if statements, loops, and the ternary operator. But no explicit cast is added just for putting ! in front of a variable. It works with something like
if(!foo) {...}
simply because that becomes
if(!cast(bool)foo) {...}
But nothing special is done for !, and !a will not call opCast.
- Jonathan M Davis
|
June 26, 2013 Re: Overload of ! operator | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Wednesday, 26 June 2013 at 05:08:07 UTC, Jonathan M Davis wrote:
> On Wednesday, June 26, 2013 06:59:14 cal wrote:
>> On Wednesday, 26 June 2013 at 04:06:05 UTC, Jonathan M Davis
>>
>> wrote:
>> > Yeah, that should work for the conditions in if, while, and for
>> > loops but
>> > won't work for anything else (_maybe_ ternary operators, but
>> > I'm not sure).
>> > So, if you need to be able to do !obj in the general case,
>> > that's not going to
>> > work
>>
>> ...
>>
>> import std.stdio;
>>
>> struct S {
>> int x;
>> bool opCast(T)() if (is(T == bool)) {
>> return x == 0;
>> }
>> }
>>
>> void main() {
>> auto s = S(1);
>> auto b = !s;
>> writeln(b); // true
>> }
>>
>> Is this not supposed to work?
>
> No, it's not. That would require an implicit cast (which requires using alias
> this). opCast gives you an explicit cast only. Where that becomes confusing is
> the fact that the compiler inserts explicitly casts to bool in conditions for
> if statements, loops, and the ternary operator. e.g.
>
> if(foo) {...}
>
> becomes
>
> if(cast(bool)foo) {...}
>
> So, if you've overloaded opCast to bool, then it'll get used in the conditions
> for if statements, loops, and the ternary operator. But no explicit cast is
> added just for putting ! in front of a variable. It works with something like
>
> if(!foo) {...}
>
> simply because that becomes
>
> if(!cast(bool)foo) {...}
>
> But nothing special is done for !, and !a will not call opCast.
>
> - Jonathan M Davis
But that code I posted does work, and gives the output shown. Am I misunderstanding?
|
Copyright © 1999-2021 by the D Language Foundation