Non Member range functions

拜拜、爱过 提交于 2019-12-10 13:57:07

问题


I have a class that I'm implementing ranges for. I'd like to implement the functions the way the phobos library does, i.e. outside the main class.

void popBack(T)(ref T[] a) if (!is(Unqual!T == char) && !is(Unqual!T == wchar))
{
    assert(a.length);
    a = a[0 .. $ - 1];
}

Here's my version:

void popFront(T)(ref PersistentList!(T) a)
{
    a = a.next();   
}

When I try to compile this code with a forech, I get:

Error   1   Error: no property 'popFront' for type 'stmd.PersistentList!(int).PersistentList'   main.d  

I could move the member code into the main class, but since I'm modifying the input "ref" value I can't use popFront() I really need popFront(ref a).

What am I doing wrong?


回答1:


What you're trying to do depends on what the D community calls uniform function call syntax. This is the ability to call non-member functions with the same syntax as member functions. This has been implemented for arrays only for a long time, and there was some debate about how far to take it. It's been decided that it should be implemented for all types, but Walter Bright, the compiler implementer hasn't gotten around to doing this yet because he's been working feverishly on 64-bit support.

Uniform function call syntax is described in Andrei Alexandrescu's book, "The D Programming Language", which is considered the authoritative guide to D2. Its currently lack of implementation is considered a bug. This should be fixed in a few releases.




回答2:


Phobos only implements the range functions outside of the struct/class for arrays. Arrays allow you to call functions on them as if they were member functions. So, if you have this function:

int func(int[] arr)
{
    return arr[0];
}

you can call it like so

auto arr = [1, 2, 3];
auto val = arr.func();

instead of

auto val = func(arr);

Being able to do that with all types is called universal function call syntax, but that's not currently legal in D, though it looks like it's probably going to be added.

There's really no reason to declare your range functions outside of your range type, unless you're looking to share that implementation with other range types, which often wouldn't be possible anyway, since the internal implementation has to deal with how the container type maintains its data. So, you might as well just make them part of your range type. That's what Phobos does in all cases, except for arrays, which obviously can't have them as part of their type and have to use their ability to have functions called on them as if they were member functions in order for it work.



来源:https://stackoverflow.com/questions/3868511/non-member-range-functions

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!