Template for function or delegate (nothing else)

spir denis.spir at gmail.com
Thu Feb 10 05:39:13 PST 2011


On 02/09/2011 11:05 PM, Steven Schveighoffer wrote:
> On Wed, 09 Feb 2011 16:41:25 -0500, useo <useo at start.bg> wrote:
>
>> == Auszug aus bearophile (bearophileHUGS at lycos.com)'s Artikel
>>> useo:
>>> > I just have a problem with my variables.
>>> >
>>> > For example... my class/template just looks like:
>>> >
>>> > class Example(T) if (is(T == delegate) || is(T == function))
>>> > {
>>> > T callback;
>>> >
>>> > void setCallback(T cb) {
>>> > callback = cb;
>>> > }
>>> >
>>> > }
>>> >
>>> > This means that I need variables like Example!(void function
>> ())
>>> > myVariable. But is there any possibility to use variables like
>>> > Example myVariable?
>>> D is not the SML language, templates are just placeholders. If
>> you don't instantiate a template, you have only a symbol. Example
>> is only assignable to an alias (and in past, to a typedef):
>>> alias Example Foo;
>>> > The template declaration only defines the type of
>>> > a callback and perhaps one method-declaration nothing else. I
>> already
>>> > tried Example!(void*) because delegates and functions are void
>>> > pointers but I always get an error. I hope there is any way
>> to do
>>> > this.
>>> I don't yet understand what you are trying to do.
>>> Other notes:
>>> - What if your T is a functor (a callable class/struct/union
>> instance that defined opCall)?
>>> - sizeof of a function pointer is 1 CPU word, while a delegate
>> is 2 CPU words (and a delegate clojure has stuff on the heap too,
>> sometimes).
>>> Bye,
>>> bearophile
>>
>> Idea is the following:
>>
>> class Example(T) if (is(T == delegate) || is(T == function)) {
>>
>> T callback;
>>
>> void setCallback(T cb) {
>> callback = cb;
>> }
>>
>> void opCall() {
>> callback();
>> }
>>
>> }
>>
>> other file:
>>
>> import example;
>>
>> private {
>>
>> Example variable;
>>
>> }
>>
>> void setExampleVariable(Example ex) {
>> variable = ex;
>> }
>>
>> void callCurrentExampleVariable() {
>> variable();
>> }
>
> I don't think you want templates. What you want is a tagged union (and a struct
> is MUCH better suited for this):
>
> // untested!
>
> struct Example
> {
> private
> {
> bool isDelegate;
> union
> {
> void function() fn;
> void delegate() dg;
> }
> }
>
> void setCallback(void function() f) { this.fn = f; isDelegate = false;}
> void setCallback(void delegate() d) { this.dg = d; isDelegate = true;}
>
> void opCall()
> {
> if(isDelegate)
> dg();
> else
> fn();
> }
> }

Waow, very nice solution.
I really question the function/delegate distinction (mostly artificial, imo) 
that "invents" issues necessiting workarounds like that. What does it mean, 
what does it bring?
Right, there is one pointer less for funcs. This save 4 or 8 bytes, so to say, 
nothing; who develops apps with arrays of billions of funcs? There are written 
in source ;-) Even then, if this saving of apointer was of any relevance, then 
it should be an implementation detail that does not leak into artificial 
semantic diff, creating issues on the programmer side. What do you think?

Denis
-- 
_________________
vita es estrany
spir.wikidot.com



More information about the Digitalmars-d-learn mailing list