View mode: basic / threaded / horizontal-split · Log in · Help
November 16, 2008
how to use opdot
Hi,

I've read about opdot in D language spec operator overload section, but the little snippet of code provided isn't enough, for me, to figure out what it is supposed to do and how to use it or what it could be usefull for.

Could you please help me to get the right way?

Thank you,

Luca.
November 19, 2008
Re: how to use opdot
Morusaka schrieb:
> Hi,
> 
> I've read about opdot in D language spec operator overload section, but the little snippet of code provided isn't enough, for me, to figure out what it is supposed to do and how to use it or what it could be usefull for.
> 
> Could you please help me to get the right way?
> 
Well, if D wasn't OO, I'd say it's some way to provide exactly that, 
e.g. the scripting language Lua does it that way: if it can't find a 
member in a table, it looks in another one specified similarly to this 
opDot way. That provides some kind of "inheritance".

But I can't currently imagine any way to use this either.
November 20, 2008
Re: how to use opdot
Hoenir Wrote:

> But I can't currently imagine any way to use this either.

it will be useful when implementing auto_ptr, shared_ptr and likes.
November 20, 2008
Re: how to use opdot
"Morusaka" wrote
> Hi,
>
> I've read about opdot in D language spec operator overload section, but 
> the little snippet of code provided isn't enough, for me, to figure out 
> what it is supposed to do and how to use it or what it could be usefull 
> for.
>
> Could you please help me to get the right way?

opDot is useful if you want to make a 'wrapper' type.  That is, you want to 
mimic another type, but you want to slightly alter the behavior.  opDot 
allows you to 'inherit' all the member functions and fields from the wrapped 
type.  For example, if I wanted to create a wrapper type that added a 
'blahblah' integer to the type, I could do this:

struct AddBlahBlah(T)
{
  T _t;
  int blahblah;

  T *opDot() { return &_t;}
}

Now, if I declare an AddBlahBlah!(C) and class C has a member foo():

C c;
AddBlahBlah!(C) abb = AddBlahBlah!(C)(c);

abb.foo(); // translates to abb.opDot().foo()
abb.blahblah = 5; // sets abb.blahblah to 5, doesn't affect _t

The goal of opDot is to allow one to create types that wrap other types that 
look almost exactly the same without much effort.  For example, the 
std.typecons.Rebindable type allows one to create a rebindable const or 
invariant class reference while forwarding all member accesses to the 
underlying invariant or const instance.  This feature is used for extending 
the type system without having to extend the language, allowing compiler 
enforcement of specific design aspects without defining them in the 
compiler.

Normal developers will most likely never need to define opDot.

-Steve
November 20, 2008
Re: how to use opdot
Steven Schveighoffer wrote:
> "Morusaka" wrote
>> Hi,
>>
>> I've read about opdot in D language spec operator overload section, but 
>> the little snippet of code provided isn't enough, for me, to figure out 
>> what it is supposed to do and how to use it or what it could be usefull 
>> for.
>>
>> Could you please help me to get the right way?
> 
> opDot is useful if you want to make a 'wrapper' type.  That is, you want to 
> mimic another type, but you want to slightly alter the behavior.  opDot 
> allows you to 'inherit' all the member functions and fields from the wrapped 
> type.  For example, if I wanted to create a wrapper type that added a 
> 'blahblah' integer to the type, I could do this:
> 
> struct AddBlahBlah(T)
> {
>    T _t;
>    int blahblah;
> 
>    T *opDot() { return &_t;}
> }
> 
> Now, if I declare an AddBlahBlah!(C) and class C has a member foo():
> 
> C c;
> AddBlahBlah!(C) abb = AddBlahBlah!(C)(c);
> 
> abb.foo(); // translates to abb.opDot().foo()
> abb.blahblah = 5; // sets abb.blahblah to 5, doesn't affect _t

Wow. That's incredibly useful for doing decorators!

http://en.wikipedia.org/wiki/Decorator_pattern
November 20, 2008
Re: how to use opdot
"Ary Borenszweig" wrote
> Steven Schveighoffer wrote:
>> "Morusaka" wrote
>>> Hi,
>>>
>>> I've read about opdot in D language spec operator overload section, but 
>>> the little snippet of code provided isn't enough, for me, to figure out 
>>> what it is supposed to do and how to use it or what it could be usefull 
>>> for.
>>>
>>> Could you please help me to get the right way?
>>
>> opDot is useful if you want to make a 'wrapper' type.  That is, you want 
>> to mimic another type, but you want to slightly alter the behavior. 
>> opDot allows you to 'inherit' all the member functions and fields from 
>> the wrapped type.  For example, if I wanted to create a wrapper type that 
>> added a 'blahblah' integer to the type, I could do this:
>>
>> struct AddBlahBlah(T)
>> {
>>    T _t;
>>    int blahblah;
>>
>>    T *opDot() { return &_t;}
>> }
>>
>> Now, if I declare an AddBlahBlah!(C) and class C has a member foo():
>>
>> C c;
>> AddBlahBlah!(C) abb = AddBlahBlah!(C)(c);
>>
>> abb.foo(); // translates to abb.opDot().foo()
>> abb.blahblah = 5; // sets abb.blahblah to 5, doesn't affect _t
>
> Wow. That's incredibly useful for doing decorators!
>
> http://en.wikipedia.org/wiki/Decorator_pattern

Not exactly ;)  The wrapped type is not equivalent to inheritance.

For example, if you have a function that takes a class C, you can't pass an 
AddBlahBlah!(C) type into it.

However, a template function which expects a type C or a wrapped C, could 
possibly be used as you say.

-Steve
November 20, 2008
Re: how to use opdot
Steven Schveighoffer wrote:
> "Ary Borenszweig" wrote
>> Steven Schveighoffer wrote:
>>> "Morusaka" wrote
>>>> Hi,
>>>>
>>>> I've read about opdot in D language spec operator overload section, but 
>>>> the little snippet of code provided isn't enough, for me, to figure out 
>>>> what it is supposed to do and how to use it or what it could be usefull 
>>>> for.
>>>>
>>>> Could you please help me to get the right way?
>>> opDot is useful if you want to make a 'wrapper' type.  That is, you want 
>>> to mimic another type, but you want to slightly alter the behavior. 
>>> opDot allows you to 'inherit' all the member functions and fields from 
>>> the wrapped type.  For example, if I wanted to create a wrapper type that 
>>> added a 'blahblah' integer to the type, I could do this:
>>>
>>> struct AddBlahBlah(T)
>>> {
>>>    T _t;
>>>    int blahblah;
>>>
>>>    T *opDot() { return &_t;}
>>> }
>>>
>>> Now, if I declare an AddBlahBlah!(C) and class C has a member foo():
>>>
>>> C c;
>>> AddBlahBlah!(C) abb = AddBlahBlah!(C)(c);
>>>
>>> abb.foo(); // translates to abb.opDot().foo()
>>> abb.blahblah = 5; // sets abb.blahblah to 5, doesn't affect _t
>> Wow. That's incredibly useful for doing decorators!
>>
>> http://en.wikipedia.org/wiki/Decorator_pattern
> 
> Not exactly ;)  The wrapped type is not equivalent to inheritance.

Ah, right. I forgot the inheritance part. :(

> 
> For example, if you have a function that takes a class C, you can't pass an 
> AddBlahBlah!(C) type into it.
> 
> However, a template function which expects a type C or a wrapped C, could 
> possibly be used as you say.
> 
> -Steve 
> 
>
November 20, 2008
Re: how to use opdot
Steven Schveighoffer Wrote:
> opDot is useful if you want to make a 'wrapper' type.  That is, you want to 
> mimic another type, but you want to slightly alter the behavior.  opDot 
> allows you to 'inherit' all the member functions and fields from the wrapped 
> type.  For example, if I wanted to create a wrapper type that added a 
> 'blahblah' integer to the type, I could do this:
> 
> struct AddBlahBlah(T)
> {
>    T _t;
>    int blahblah;
> 
>    T *opDot() { return &_t;}
> }
> 
> Now, if I declare an AddBlahBlah!(C) and class C has a member foo():
> 
> C c;
> AddBlahBlah!(C) abb = AddBlahBlah!(C)(c);
> 
> abb.foo(); // translates to abb.opDot().foo()
> abb.blahblah = 5; // sets abb.blahblah to 5, doesn't affect _t
> 
> The goal of opDot is to allow one to create types that wrap other types that 
> look almost exactly the same without much effort.  For example, the 
> std.typecons.Rebindable type allows one to create a rebindable const or 
> invariant class reference while forwarding all member accesses to the 
> underlying invariant or const instance.  This feature is used for extending 
> the type system without having to extend the language, allowing compiler 
> enforcement of specific design aspects without defining them in the 
> compiler.
> 
> Normal developers will most likely never need to define opDot.
> 
> -Steve 
> 
> 

Thank you very much Steven!

Luca
November 21, 2008
Re: how to use opdot
Steven Schveighoffer wrote:
> Not exactly ;)  The wrapped type is not equivalent to inheritance.

No, exactly:

class Wrapper(T) : T
{
	T opDot() {}
}
November 21, 2008
Re: how to use opdot
"Christopher Wright" wrote
> Steven Schveighoffer wrote:
>> Not exactly ;)  The wrapped type is not equivalent to inheritance.
>
> No, exactly:
>
> class Wrapper(T) : T
> {
> T opDot() {}
> }

class Wrapper(T) : T
{
}

works just as good ;)

-Steve
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home