OPTLINK checkpoint(256)
I was still using 2.066.1. When I try to build using 2.067.0 or 2.067.1 I get: Linking... checkpoint(256) --- errorlevel 1 with an Unexpected OPTLINK Termination popup which lists a bunch of registers. I'm not sure how to proceed..
Static function template
Is it not possible to have a static function template with the same name as the non-static version? struct S { int i; auto foo(T)(int j) { i=j; } static auto foo(T)(int j) { S s; s.foo!T(j); return s; } } void main() { auto s = S.foo!bool(1); } Error: need 'this' for 'foo' of type '(int j)'
Re: Static function template
On Thursday, 7 May 2015 at 10:43:28 UTC, Daniel Kozak wrote: On Thursday, 7 May 2015 at 10:39:09 UTC, Daniel Kozák wrote: On Thu, 07 May 2015 10:33:44 + Vadim Lopatin via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: struct S { int i; auto foo2(T)(int j) { i=j; } static S foo(T)(int j) { S s; s.foo2!T(j); return s; } } void main() { auto s = S.foo!bool(1); } As I said, it is not bug. It is OK. There is no way how you can distinguish between static and non static methods or even field in some cases. e.g.: import std.stdio; struct S { string foo = Please select me?; string foo() { return (No, select me?); }; static string foo() { return (I am better than the otters :D?); }; } void main() { auto s = S(); writeln(s.foo); } Well it's clear to me now why it shouldn't work. However, the error msg is not clear on the problem. Imo it should give a conflict error like in your previous example. That would make it clear what's happened/allowed. The current error seemed like it matched the wrong template, prompting me to look for a buggy function template implementation.
Template mixin enum stringof
Consider the following: --- enum Foo { BAR, } mixin template S(string s_) { enum s = s_; } void main() { mixin S!(Foo.BAR.stringof); // Error: identifier 'stringof' of 'Foo.BAR.stringof' is not defined enum e = Foo.BAR.stringof; mixin S!(e); // works fine } --- Why doesn't the first work? And is there an alternative to the second version?
Re: Template mixin enum stringof
On Wednesday, 10 December 2014 at 12:08:34 UTC, ketmar via Digitalmars-d-learn wrote: On Wed, 10 Dec 2014 11:52:11 + Lemonfiend via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: Consider the following: --- enum Foo { BAR, } mixin template S(string s_) { enum s = s_; } void main() { mixin S!(Foo.BAR.stringof); // Error: identifier 'stringof' of 'Foo.BAR.stringof' is not defined enum e = Foo.BAR.stringof; mixin S!(e); // works fine } --- Why doesn't the first work? And is there an alternative to the second version? mixin S!((Foo.BAR).stringof); sorry, don't remember the parsing rule for this. Wow, I didn't even consider that.. Thanks!
Re: Template mixin enum stringof
On Wednesday, 10 December 2014 at 12:57:07 UTC, Daniel Kozák via Digitalmars-d-learn wrote: V Wed, 10 Dec 2014 12:35:44 + Lemonfiend via Digitalmars-d-learn digitalmars-d-learn@puremagic.com napsáno: On Wednesday, 10 December 2014 at 12:08:34 UTC, ketmar via Digitalmars-d-learn wrote: On Wed, 10 Dec 2014 11:52:11 + Lemonfiend via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: Consider the following: --- enum Foo { BAR, } mixin template S(string s_) { enum s = s_; } void main() { mixin S!(Foo.BAR.stringof); // Error: identifier 'stringof' of 'Foo.BAR.stringof' is not defined enum e = Foo.BAR.stringof; mixin S!(e); // works fine } --- Why doesn't the first work? And is there an alternative to the second version? mixin S!((Foo.BAR).stringof); sorry, don't remember the parsing rule for this. Wow, I didn't even consider that.. Thanks! Note: Using .stringof for code generation is not recommended, as the internal representation of a type or expression can change between different compiler versions. http://dlang.org/property#stringof Ah, thanks for the warning!
Re: Template mixin enum stringof
On Wednesday, 10 December 2014 at 12:57:16 UTC, ketmar via Digitalmars-d-learn wrote: On Wed, 10 Dec 2014 12:35:44 + Lemonfiend via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: On Wednesday, 10 December 2014 at 12:08:34 UTC, ketmar via Digitalmars-d-learn wrote: On Wed, 10 Dec 2014 11:52:11 + Lemonfiend via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: Consider the following: --- enum Foo { BAR, } mixin template S(string s_) { enum s = s_; } void main() { mixin S!(Foo.BAR.stringof); // Error: identifier 'stringof' of 'Foo.BAR.stringof' is not defined enum e = Foo.BAR.stringof; mixin S!(e); // works fine } --- Why doesn't the first work? And is there an alternative to the second version? mixin S!((Foo.BAR).stringof); sorry, don't remember the parsing rule for this. Wow, I didn't even consider that.. Thanks! also, you can use this: import std.conv : to; ... mixin S!(to!string(Foo.BAR)); people tend to forget that many `to!` variants are usable in CTFE. Seems like I'd want to move the converting-to-string functionality to within the template mixin then, something like: --- mixin template S(T, T t) if (is(T == enum)) { //import std.traits; //enum s = fullyQualifiedName!(t); // unfortunately this results in t import std.conv: to; enum s = to!string(t); // this works } mixin S!(Foo, Foo.BAR); --- But passing an enum as parameter seems to be somewhat annoying. If I leave off the first Foo, then it complains about no-matching template for int parameter. !(Foo, Foo.BAR) seems kinda redundant..
Re: Template mixin enum stringof
On Wednesday, 10 December 2014 at 14:25:30 UTC, ketmar via Digitalmars-d-learn wrote: On Wed, 10 Dec 2014 13:58:20 + Lemonfiend via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: On Wednesday, 10 December 2014 at 12:57:16 UTC, ketmar via Digitalmars-d-learn wrote: On Wed, 10 Dec 2014 12:35:44 + Lemonfiend via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: On Wednesday, 10 December 2014 at 12:08:34 UTC, ketmar via Digitalmars-d-learn wrote: On Wed, 10 Dec 2014 11:52:11 + Lemonfiend via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: Consider the following: --- enum Foo { BAR, } mixin template S(string s_) { enum s = s_; } void main() { mixin S!(Foo.BAR.stringof); // Error: identifier 'stringof' of 'Foo.BAR.stringof' is not defined enum e = Foo.BAR.stringof; mixin S!(e); // works fine } --- Why doesn't the first work? And is there an alternative to the second version? mixin S!((Foo.BAR).stringof); sorry, don't remember the parsing rule for this. Wow, I didn't even consider that.. Thanks! also, you can use this: import std.conv : to; ... mixin S!(to!string(Foo.BAR)); people tend to forget that many `to!` variants are usable in CTFE. Seems like I'd want to move the converting-to-string functionality to within the template mixin then, something like: --- mixin template S(T, T t) if (is(T == enum)) { //import std.traits; //enum s = fullyQualifiedName!(t); // unfortunately this results in t import std.conv: to; enum s = to!string(t); // this works } mixin S!(Foo, Foo.BAR); --- But passing an enum as parameter seems to be somewhat annoying. If I leave off the first Foo, then it complains about no-matching template for int parameter. !(Foo, Foo.BAR) seems kinda redundant.. something like this? mixin template S(alias fld) if (is(typeof(fld) == enum)) { import std.conv : to; enum s = to!string(fld); // BAR // or this: //import std.traits : fullyQualifiedName; //enum s = to!string(fullyQualifiedName!(fld)); // test.Foo.BAR } enum Foo { BAR, } void main() { mixin S!(Foo.BAR); } Perfect, thanks.
Re: alias overloaded function template
The problem is not the alias. The error message is about using the same identifier for two different things: C:\...\temp_0186F968.d(13,1): Error: declaration foo(T)(T t, int i) is already defined. I'm not sure what is giving you that particular error. Without the alias it compiles and runs fine for me. When I wrap them individually in the template statement, it gives: --- src\app.d(24): Error: template app.foo cannot deduce function from argument types !()(int), candidates are: src\app.d(40):app.foo(T) src\app.d(45):app.foo(T) --- When I wrap them together, I can indeed alias it, thanks! What you seem to forget is that the declarations: - void foo(T)(T t) {} void foo(T)(T t, int i) {} - are actually a two **Eponymous template** with the same name: - template foo(T){ void foo(T t) {} } template foo(T){ void foo(T t, int i) {} } - Yes I had forgotten, assuming I ever knew :)
How to use map?
I'm trying to do something simple like creating an array of struct S from a float array via map: --- void main() { float[] vals = [1.1, 2.1, 3.1, 4.1]; import std.algorithm: map; auto arr = vals.map!`S(a)`.array; writeln(arr); } struct S(T) { T t; } --- But I get: --- C:\D\dmd2\windows\bin\..\..\src\phobos\std\functional.d-mixin-49(49): Error: undefined identifier S C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(480): Error: template instance std.functional.unaryFun!(S(a), a).unaryFun!float error instantiating C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(427): instantiated from here: MapResult!(unaryFun, float[]) src\app.d(28):instantiated from here: map!(float[]) --- If I instead do ie. map!`cast(int)a` it works fine. What am I missing?
Re: How to use map?
The code you were trying to write: struct Foo(T) { T t; } void main() { import std.stdio, std.algorithm, std.array; float[] vals = [1.1, 2.1, 3.1, 4.1]; auto arr = vals.map!(Foo!float).array; arr.writeln; } Sorry, my example had an unneeded template. Simply this (and also your code) --- struct S { float f; } --- still results in an undefined identifier.
Re: How to use map?
Oh, no it doesn't. My bad. It was all about !(Foo) vs !(`Foo(a)`). Is there somewhere I can read more about this?
Re: How to use map?
On Tuesday, 11 November 2014 at 15:53:37 UTC, Marc Schütz wrote: Don't know whether it's documented, but it's a consequence of using string mixins. unaryFun (which is used internally by map) is implemented this way: auto unaryFun(ElementType)(auto ref ElementType __a) { mixin(alias ~ parmName ~ = __a ;); return mixin(fun); } where `fun` is `Foo(a)`. Of course, `Foo` is not visible in std.functional. When you pass in a symbol, the lookup work because it takes place at the point of instantiation. That makes sense, thanks.
alias overloaded function template
D is fine with alias this overloaded function: --- void foo(int t) {} void foo(int t, int i) {} alias bar = foo; --- But isn't as happy aliasing these function templates: --- void foo(T)(T t) {} void foo(T)(T t, int i) {} alias bar = foo!int; --- Is there some way/other syntax to make an alias like this work? Or specify in the alias which function template to use (ie. alias bar = foo!int(int)).
Bug when overload function in multiple modules?
I get: src\app.d(19): Error: None of the overloads of 'foo' are callable using argument types (C3), candidates are: src\app.d(28):main.foo(C1 c) src\app.d(38):main.foo(C2 c) It does work when I explicitly import c3.foo. --- file app.d module app; import std.stdio; import c3; //import c3:foo; //uncomment this and it works void main() { C1 c1 = new C1(); c1.foo(); writeln(c1.i); C2 c2 = new C2(); c2.foo(); writeln(c2.i); C3 c3 = new C3(); c3.foo(); writeln(c3.i); } class C1 { int i; } void foo(C1 c) { c.i = 1; } class C2 { int i; } void foo(C2 c) { c.i = 2; } --- file c3.d module c3; class C3 { int i; } void foo(C3 c) { c.i = 3; }
SList: How do I use linearRemove?
--- module main; void main() { struct Tree { int apples; } import std.container; SList!Tree list; Tree tree = Tree(5); list.insert(tree); //list.linearRemove(tree); // -- Error. What is the correct way? } ---
Re: SList: How do I use linearRemove?
linearRemove is linear, so I think it accepts a range. Perhaps the once range is enough. I cannot find once in the docs. Did you mean std.range.only? Error: function std.container.SList!(Tree).SList.linearRemove (Range r) is not callable using argument types (OnlyResult!(Tree, 1u))
Re: SList: How do I use linearRemove?
unittest { auto s = SList!int(1, 2, 3, 4, 5); auto r = s[]; popFrontN(r, 3); auto r1 = s.linearRemove(r); assert(s == SList!int(1, 2, 3)); assert(r1.empty); } This works: auto s = SList!int(1, 2, 3, 4, 5); auto r = s[]; popFrontN(r, 1); auto r1 = s.linearRemove(r); This doesn't (why?): auto s = SList!int(1, 2, 3, 4, 5); auto r = s[]; auto r1 = s.linearRemove(r); This doesn't (why?): auto s = SList!int(1, 2, 3, 4, 5); auto s2 = SList!int(1, 2, 3, 4, 5); auto r = s2[]; popFrontN(r, 1); auto r1 = s.linearRemove(r); I am at a loss..