Thread overview
Deep flaw with D's template mechanism
Jul 16, 2004
Matthew Wilson
Jul 16, 2004
Matthew Wilson
Jul 16, 2004
Ben Hinkle
Jul 16, 2004
Sean Kelly
Jul 16, 2004
Matthew
Jul 16, 2004
Walter
Jul 16, 2004
Matthew
July 16, 2004
Ok, here's where I'm at with working on DTL. I'm pretty sure I've hit some fundamental limitations of D, that probably need to be changed.

I have a template member function of a container called select(), which returns a collection-set - (for the moment, don't worry about what one of those is) - of all elements which match a certain predicate.

Container
{
    template select(F) { final MatchedNotionalRange!(range_type, F) select(F
f = new F())
    {
        return new MatchedNotionalRange!(range_type, F)(opSlice(), f);
    }}


Note that the function is defaulted, so that one can write things such as the following:

    printf("\nselect()-ing the numbers, with IsOdd\n");
    foreach(int i; cont.select!(IsOdd)())
    {
        printf("%d ", i);
    }
    printf("\n");

Since many functors are default constructed, it's advantageous to be able to default the argument to select().

However, when we wish to use a functor that needs non-default construction, we run into some snags. The " = new F()" requires that the functor be default constructible.

Now, if we could overload template member functions, this would not be an issue, since we could separate select() into two functions, as follows:


Container
{
    template select(F) { final MatchedNotionalRange!(range_type, F) select(F
f)
    {
        return new MatchedNotionalRange!(range_type, F)(opSlice(), f);
    }}

    template select(F) { final MatchedNotionalRange!(range_type, F) select()
    {
        return new MatchedNotionalRange!(range_type, F)(opSlice(), new F());
    }}


Then all would be happy.

If we can't have this, then we will have to stipulate functors twice, as follows:

        foreach(int i; cont.select!(IsOdd)(new IsOdd()))
        {
            . . .

This is tedious.

Walter, what do you think?



July 16, 2004
Hmm. The title of this sounds a bit portentous. I meant to include other, related, problems, but am holding off to see if I can find acceptable workarounds

So, think of it as "Serious flaw with ..."

And now to bed, I think. Too many hours thinking about D for me today.



"Matthew Wilson" <admin.hat@stlsoft.dot.org> wrote in message news:cd8kek$7kh$1@digitaldaemon.com...
> Ok, here's where I'm at with working on DTL. I'm pretty sure I've hit some fundamental limitations of D, that probably need to be changed.
>
> I have a template member function of a container called select(), which returns a collection-set - (for the moment, don't worry about what one of those is) - of all elements which match a certain predicate.
>
> Container
> {
>     template select(F) { final MatchedNotionalRange!(range_type, F)
select(F
> f = new F())
>     {
>         return new MatchedNotionalRange!(range_type, F)(opSlice(), f);
>     }}
>
>
> Note that the function is defaulted, so that one can write things such as the following:
>
>     printf("\nselect()-ing the numbers, with IsOdd\n");
>     foreach(int i; cont.select!(IsOdd)())
>     {
>         printf("%d ", i);
>     }
>     printf("\n");
>
> Since many functors are default constructed, it's advantageous to be able
to
> default the argument to select().
>
> However, when we wish to use a functor that needs non-default
construction,
> we run into some snags. The " = new F()" requires that the functor be
> default constructible.
>
> Now, if we could overload template member functions, this would not be an issue, since we could separate select() into two functions, as follows:
>
>
> Container
> {
>     template select(F) { final MatchedNotionalRange!(range_type, F)
select(F
> f)
>     {
>         return new MatchedNotionalRange!(range_type, F)(opSlice(), f);
>     }}
>
>     template select(F) { final MatchedNotionalRange!(range_type, F)
select()
>     {
>         return new MatchedNotionalRange!(range_type, F)(opSlice(), new
F());
>     }}
>
>
> Then all would be happy.
>
> If we can't have this, then we will have to stipulate functors twice, as follows:
>
>         foreach(int i; cont.select!(IsOdd)(new IsOdd()))
>         {
>             . . .
>
> This is tedious.
>
> Walter, what do you think?
>
>
>


July 16, 2004
silly question: why is select a template? Why not just make the selection function (or delegate) an input? I haven't delved into STL implementations before so I don't know all the C++ template tricks needed to get it working but from a users point of view one just passes the function and it works, right? If the Container is parameterized by the type T doesn't the selection function should type int delegate(T val)? Variations would include inout T val or function instead of delegate but basically it's all there.

"Matthew Wilson" <admin.hat@stlsoft.dot.org> wrote in message news:cd8kek$7kh$1@digitaldaemon.com...
> Ok, here's where I'm at with working on DTL. I'm pretty sure I've hit some fundamental limitations of D, that probably need to be changed.
>
> I have a template member function of a container called select(), which returns a collection-set - (for the moment, don't worry about what one of those is) - of all elements which match a certain predicate.
>
> Container
> {
>     template select(F) { final MatchedNotionalRange!(range_type, F)
select(F
> f = new F())
>     {
>         return new MatchedNotionalRange!(range_type, F)(opSlice(), f);
>     }}
>
>
> Note that the function is defaulted, so that one can write things such as the following:
>
>     printf("\nselect()-ing the numbers, with IsOdd\n");
>     foreach(int i; cont.select!(IsOdd)())
>     {
>         printf("%d ", i);
>     }
>     printf("\n");
>
> Since many functors are default constructed, it's advantageous to be able
to
> default the argument to select().
>
> However, when we wish to use a functor that needs non-default
construction,
> we run into some snags. The " = new F()" requires that the functor be
> default constructible.
>
> Now, if we could overload template member functions, this would not be an issue, since we could separate select() into two functions, as follows:
>
>
> Container
> {
>     template select(F) { final MatchedNotionalRange!(range_type, F)
select(F
> f)
>     {
>         return new MatchedNotionalRange!(range_type, F)(opSlice(), f);
>     }}
>
>     template select(F) { final MatchedNotionalRange!(range_type, F)
select()
>     {
>         return new MatchedNotionalRange!(range_type, F)(opSlice(), new
F());
>     }}
>
>
> Then all would be happy.
>
> If we can't have this, then we will have to stipulate functors twice, as follows:
>
>         foreach(int i; cont.select!(IsOdd)(new IsOdd()))
>         {
>             . . .
>
> This is tedious.
>
> Walter, what do you think?
>
>
>


July 16, 2004
Maybe I'm missing something, but can't you do this?:

template select(F) {
final MatchedNotionalRange!(range_type, F) select(F f)
{
return new MatchedNotionalRange!(range_type, F)(opSlice(), f);
}

final MatchedNotionalRange!(range_type, F) select()
{
return new MatchedNotionalRange!(range_type, F)(opSlice(), new F());
}
}


Sean


July 16, 2004
Instead of having two separate templates, have one template with both functions inside it.


July 16, 2004
Alas no. Overloading member templates is not supported. I want that support

"Sean Kelly" <sean@f4.ca> wrote in message news:cd8s6f$b77$1@digitaldaemon.com...
> Maybe I'm missing something, but can't you do this?:
>
> template select(F) {
> final MatchedNotionalRange!(range_type, F) select(F f)
> {
> return new MatchedNotionalRange!(range_type, F)(opSlice(), f);
> }
>
> final MatchedNotionalRange!(range_type, F) select()
> {
> return new MatchedNotionalRange!(range_type, F)(opSlice(), new F());
> }
> }
>
>
> Sean
>
>


July 16, 2004
"Walter" <newshound@digitalmars.com> wrote in message news:cd955a$faj$1@digitaldaemon.com...
> Instead of having two separate templates, have one template with both functions inside it.

Doesn't work. If a member template has anything at all - an alias, a function - before the one function, it gives an error like "function expected before (), not 'cont dotexp template instance select!(IsOdd)' and the file/line is the client code call site.

If I knock up a small example to demonstrate this, can you effect a fix in the next few hrs, so I can proceed?