digitalmars.D.learn - Weird UFC and opCall issues
- Jay Pinkman (15/15) Dec 17 2014 void main () {
- Adam D. Ruppe (7/10) Dec 17 2014 D doesn't have a really clean separation between static and
- Jay Pinkman (7/13) Dec 17 2014 hmm.. i thought that's what 'static' is for.
- Darrell (25/25) Jan 03 2015 Fails with:
- Darrell (5/30) Jan 03 2015 Ooops.
- Darrell (19/19) Jan 03 2015 Seems when creating your own ranges they can't be a class.
- ted (25/50) Jan 03 2015 With classes, you need to create an instance, so (adjusting some of your...
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (45/70) Jan 03 2015 D has a feature that does not exists e.g. in C++: You can call the type
- Darrell (14/15) Jan 03 2015 Need to read up classes vs struct.
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?
Dec 17 2014
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.
Dec 17 2014
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.
Dec 17 2014
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(); }
Jan 03 2015
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(); }
Jan 03 2015
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)); }
Jan 03 2015
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)); }
Jan 03 2015
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
Jan 03 2015
Thanks for the feedback.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.With classes, you need to create an instance
Jan 03 2015