Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
December 18, 2014 Weird UFC and opCall issues | ||||
---|---|---|---|---|
| ||||
void main () { struct X { string x; void opCall (string y) { import std.stdio; writeln("%s %s!", x, y); } } auto x = X("hello"); "world".x; } source/main.d(12): Error: need 'this' for 'opCall' of type 'void(string y)' source/main.d(13): Error: no property 'x' for type 'string' but why? |
December 18, 2014 Re: Weird UFC and opCall issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jay Pinkman | On Thursday, 18 December 2014 at 02:42:32 UTC, Jay Pinkman wrote: > source/main.d(12): Error: need 'this' for 'opCall' of type 'void(string y)' D doesn't have a really clean separation between static and non-static methods. It sees an opCall and thinks you're trying to call it, but since it isn't static, it complains you don't have a this. > source/main.d(13): Error: no property 'x' for type 'string' I don't think UFCS works with structs nor local variables anyway, so this error makes sense to me. |
December 18, 2014 Re: Weird UFC and opCall issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Thursday, 18 December 2014 at 02:45:01 UTC, Adam D. Ruppe wrote: > D doesn't have a really clean separation between static and non-static methods. hmm.. i thought that's what 'static' is for. > It sees an opCall and thinks you're trying to call it, but since it isn't static, it complains you don't have a this. so it's bug i should report or some idiosyncracy? > I don't think UFCS works with structs nor local variables anyway, so this error makes sense to me. i guess i should request this. in my other code i use a struct to represent a transformation so it makes perfect sense to use it in UFCS fashion. |
January 03, 2015 Re: Weird UFC and opCall issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | Fails with: t.d(34): Error: need 'this' for 'opCall' of type 'int()' Also opCall seems to be required to create a range. class Test { int opCall() { return 1; } @property int front() { return 2; } void popFront() { } @property bool empty() { return false; } }; void main(){ ubyte [] p1; Test(); } |
January 03, 2015 Re: Weird UFC and opCall issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to Darrell | Ooops.
Test() wasn't valid.
Still working to create a range object that iterates over an internal data struct. But this was may error.
On Saturday, 3 January 2015 at 20:26:41 UTC, Darrell wrote:
> Fails with:
> t.d(34): Error: need 'this' for 'opCall' of type 'int()'
>
> Also opCall seems to be required to create a range.
>
> class Test
> {
> int opCall()
> {
> return 1;
> }
>
> @property int front()
> {
> return 2;
> }
>
> void popFront()
> {
> }
>
> @property bool empty()
> {
> return false;
> }
>
> };
>
> void main(){
> ubyte [] p1;
> Test();
> }
|
January 03, 2015 Re: Weird UFC and opCall issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to Darrell | Seems when creating your own ranges they can't be a class. Must be a struct or Segmentation fault (core dumped) will follow. This works as long as Test is a struct. struct Test { @property int front() { return 2; } void popFront() { } enum bool empty = false; }; static assert(isInputRange!Test); void mainx(){ Test x; writeln(x.take(1)); } |
January 03, 2015 Re: Weird UFC and opCall issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to Darrell | Darrell wrote:
> Seems when creating your own ranges they can't be a class.
> Must be a struct or Segmentation fault (core dumped) will follow.
>
> This works as long as Test is a struct.
>
> struct Test
> {
> @property int front()
> {
> return 2;
> }
>
> void popFront()
> {
> }
>
> enum bool empty = false;
> };
>
> static assert(isInputRange!Test);
>
> void mainx(){
> Test x;
> writeln(x.take(1));
> }
With classes, you need to create an instance, so (adjusting some of your previous code) this works:
import std.range;
import std.stdio;
class Test
{
@property int front()
{
return 2;
}
void popFront()
{
}
@property bool empty()
{
return false;
}
};
static assert(isInputRange!Test);
void main(){
ubyte [] p1;
Test myTest = new Test();
writeln(myTest.take(1));
}
|
January 03, 2015 Re: Weird UFC and opCall issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to Darrell | On 01/03/2015 12:26 PM, Darrell wrote: > Fails with: > t.d(34): Error: need 'this' for 'opCall' of type 'int()' > > Also opCall seems to be required to create a range. D has a feature that does not exists e.g. in C++: You can call the type itself as a function. The 'Test()' syntax is a call to that type's static opCall(). > > class Test > { > int opCall() > { > return 1; > } Not being static, that would require an instance of the Test class. > > @property int front() > { > return 2; > } You may want to define that member function 'const' as well. > > void popFront() > { > } > > @property bool empty() > { > return false; > } That can be 'const' as well. > > }; D does not require that semicolon. > > void main(){ > ubyte [] p1; > Test(); > } I am removing the opCall and assuming that you actually want a ubyte I am returning a ubyte from front(). Also note the almost-mandatory-with-ranges convenience function 'test()' below, which hides the invocation of 'new': class Test { @property ubyte front() { return 2; } void popFront() { } @property bool empty() { return false; } } Test test() { return new Test(); } /* Alternatively, you can move test() inside Test as a static opCall: static Test opCall() { return new Test(); } Then, the syntax in main could be ubyte [] p1 = Test().take(3).array; */ import std.stdio; import std.range; void main(){ ubyte [] p1 = test().take(3).array; assert(p1 == [ 2, 2, 2 ]); } Ali |
January 03, 2015 Re: Weird UFC and opCall issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Thanks for the feedback.
>> With classes, you need to create an instance
Need to read up classes vs struct.
This bit of syntax was very intresting.
/* Alternatively, you can move test() inside Test as a static opCall:
static Test opCall()
{
return new Test();
}
Then, the syntax in main could be
ubyte [] p1 = Test().take(3).array;
*/
Very impressed with D and starting a new job. Might be able to use it.
|
Copyright © 1999-2021 by the D Language Foundation