inout template parameter, or a solution to the templated container issue

Steven Schveighoffer schveiguy at yahoo.com
Thu Jun 13 06:39:09 PDT 2013


On Wed, 12 Jun 2013 22:54:19 -0400, deadalnix <deadalnix at gmail.com> wrote:

> On Wednesday, 12 June 2013 at 19:00:28 UTC, Steven Schveighoffer wrote:
>> Yes, I could introduce it like this:
>>
>> struct range(inout U) if(is(U == T))
>> {
>>    size_t length;
>>    U *ptr;
>> }
>>
>> but it feels unnecessary.  I also find the usage for this solution  
>> clumsy.
>>
>
> Why would you need to do it ? Why not simply do :
>
> class Container(T) {
>      struct range {
>          size_t length;
>          T* ptr;
>      }
> }

if, for instance, I want to accept a container and promise not to modify  
the elements, I would have:

void foo(const Container!int cont);

OK, so, in order to access a range of elements from the container, the  
container would have some kind of function, like:

range findAll(T elem);

How to mark up this function so it's callable on a const Container?

For C++, their solution (at least for C++03, I haven't checked how this  
works for C++11) is to simply define iterator and const_iterator  
separately, and then each function is duplicated, one that returns  
iterator and one that is const and returns const_iterator.

But I don't like that :)  I want to use inout to avoid duplication.  I  
*also* want to have a function like this:

void processRange(R)(R r) if(isInputRange!R)

And mark up processRange so *it* states that it won't modify the data.   
Then I can do:

processRange(cont.findAll(1));

on a mutable C named cont.

Basically, I'm spoiled by how well D slices work :)  I want the same power.

-Steve


More information about the Digitalmars-d mailing list