digitalmars.D.learn - Template function that accept strings and array of strings
- badlink (15/15) Jul 15 2015 Hello, I can't figure how to write a template function that
- Vlad Levenfeld (8/24) Jul 15 2015 T is already a type, so typeof(T) is an error, which makes the
- Yuxuan Shui (5/21) Jul 15 2015 T is already a type, you don't need to typeof() it.
- Jacob Carlborg (18/31) Jul 15 2015 If I understand you correctly, I think you want a type safe variadic
- badlink (16/16) Jul 16 2015 Thank you for all answers.
- Jacob Carlborg (6/10) Jul 17 2015 I don't think I really understand how you want to use/call the function....
- badlink (4/7) Jul 17 2015 My fault, I didn't test the variadic function enough and jumped
- Jacob Carlborg (5/8) Jul 17 2015 Cool :)
- Gary Willoughby (31/47) Jul 16 2015 Something like this:
- Gary Willoughby (2/2) Jul 16 2015 Also checkout inout functions:
- badlink (8/11) Jul 16 2015 Thank you ! I completely missed isSomeString.
- badlink (8/8) Jul 16 2015 After a thorough reading of the documentation I found an even
Hello, I can't figure how to write a template function that accept either strings or array of strings. This is my current code: bool hasItemParent(T)(const(char)[] itemId, const(T)[] parentId) if (is(typeof(T) == char) || (isArray!T && is(typeof(T[]) == char))) {...} I used const(T)[] because I'd like to accept immutable and mutable strings. But calling it with an immutable string generate this error: Error: template cache.MetadataCache.hasItemParent cannot deduce function from argument types !()(string, string), candidates are: cache.MetadataCache.hasItemParent(T)(const(char)[] itemId, const(T)[] parentId) if (is(typeof(T) == char)) Any suggestions ?
Jul 15 2015
On Wednesday, 15 July 2015 at 21:57:50 UTC, badlink wrote:Hello, I can't figure how to write a template function that accept either strings or array of strings. This is my current code: bool hasItemParent(T)(const(char)[] itemId, const(T)[] parentId) if (is(typeof(T) == char) || (isArray!T && is(typeof(T[]) == char))) {...} I used const(T)[] because I'd like to accept immutable and mutable strings. But calling it with an immutable string generate this error: Error: template cache.MetadataCache.hasItemParent cannot deduce function from argument types !()(string, string), candidates are: cache.MetadataCache.hasItemParent(T)(const(char)[] itemId, const(T)[] parentId) if (is(typeof(T) == char)) Any suggestions ?T is already a type, so typeof(T) is an error, which makes the constraint fail. Try hasItemParent(T)(const(char)[] itemId, const(T)[] parentId) if (is(T == char) || is (T == char[])) at least I think that's what you meant. typeof(anything[]) will never == char.
Jul 15 2015
On Wednesday, 15 July 2015 at 21:57:50 UTC, badlink wrote:Hello, I can't figure how to write a template function that accept either strings or array of strings. This is my current code: bool hasItemParent(T)(const(char)[] itemId, const(T)[] parentId) if (is(typeof(T) == char) || (isArray!T && is(typeof(T[]) == char))) {...} I used const(T)[] because I'd like to accept immutable and mutable strings. But calling it with an immutable string generate this error: Error: template cache.MetadataCache.hasItemParent cannot deduce function from argument types !()(string, string), candidates are: cache.MetadataCache.hasItemParent(T)(const(char)[] itemId, const(T)[] parentId) if (is(typeof(T) == char)) Any suggestions ?T is already a type, you don't need to typeof() it. This should work: bool hasItemParent(T)(const(char)[] itemId, const(T)[] parentId) if (is(T == char) || (isArray!T && is(ElementType!T == char)))
Jul 15 2015
On 2015-07-15 23:57, badlink wrote:Hello, I can't figure how to write a template function that accept either strings or array of strings. This is my current code: bool hasItemParent(T)(const(char)[] itemId, const(T)[] parentId) if (is(typeof(T) == char) || (isArray!T && is(typeof(T[]) == char))) {...} I used const(T)[] because I'd like to accept immutable and mutable strings. But calling it with an immutable string generate this error: Error: template cache.MetadataCache.hasItemParent cannot deduce function from argument types !()(string, string), candidates are: cache.MetadataCache.hasItemParent(T)(const(char)[] itemId, const(T)[] parentId) if (is(typeof(T) == char)) Any suggestions ?If I understand you correctly, I think you want a type safe variadic function: void foo (const(char[])[] args ...) { writeln(args); } void main() { foo("foo", "bar"); foo("foo".dup, "bar".dup); auto a = ["foo", "bar"]; foo(a); auto b = ["foo".dup, "bar".dup]; foo(b); } -- /Jacob Carlborg
Jul 15 2015
Thank you for all answers. Removing typeof do resolve the problem when the second parameter is a simple string. However when passing an array of string the error still occur: Error: template cache.MetadataCache.hasItemParent cannot deduce function from argument types !()(string, string[]). The method with the variadic function works, but I would have to use only one parameter because this doesn't work: fun(const(char[])[] a, const(char[])[] b ...) and is a bit ugly in my use case ... After some tests I found that: if (is(T == char) || is(T == string)) works, so I assume the problem is the immutable nature of string that breaks the type checking. What should I use to enable this function to accept all combinations char[], const(char)[], and immutable(char) ?
Jul 16 2015
On 2015-07-16 18:49, badlink wrote:The method with the variadic function works, but I would have to use only one parameter because this doesn't work: fun(const(char[])[] a, const(char[])[] b ...) and is a bit ugly in my use case ...I don't think I really understand how you want to use/call the function. Could you give an example with all the different types you want to call the function? -- /Jacob Carlborg
Jul 17 2015
On Friday, 17 July 2015 at 12:58:58 UTC, Jacob Carlborg wrote:I don't think I really understand how you want to use/call the function. Could you give an example with all the different types you want to call the function?My fault, I didn't test the variadic function enough and jumped to conclusion. It actually works well http://pastebin.com/R4EHuBLh
Jul 17 2015
On 2015-07-17 19:25, badlink wrote:My fault, I didn't test the variadic function enough and jumped to conclusion. It actually works well http://pastebin.com/R4EHuBLhCool :) Sometimes D developers think templates will be needed to solve everything. -- /Jacob Carlborg
Jul 17 2015
On Wednesday, 15 July 2015 at 21:57:50 UTC, badlink wrote:Hello, I can't figure how to write a template function that accept either strings or array of strings. This is my current code: bool hasItemParent(T)(const(char)[] itemId, const(T)[] parentId) if (is(typeof(T) == char) || (isArray!T && is(typeof(T[]) == char))) {...} I used const(T)[] because I'd like to accept immutable and mutable strings. But calling it with an immutable string generate this error: Error: template cache.MetadataCache.hasItemParent cannot deduce function from argument types !()(string, string), candidates are: cache.MetadataCache.hasItemParent(T)(const(char)[] itemId, const(T)[] parentId) if (is(typeof(T) == char)) Any suggestions ?Something like this: import std.stdio; import std.traits; import std.range; bool hasItemParent(A, B)(A itemId, B parentId) if (isSomeString!(A) && (isSomeString!(B) || isArray!(B) && isSomeString!(ElementType!(B)))) { writefln("%s", typeof(parentId).stringof); return true; } void main(string[] args) { string one = "foo"; char[] two = "foo".dup; const(char)[] three = "foo"; immutable(char)[] four = "foo"; string[] five = ["foo", "bar"]; char[][] six = ["foo".dup, "bar".dup]; const(char)[][] seven = ["foo", "bar"]; immutable(char)[][] eight = ["foo", "bar"]; hasItemParent(one, one); hasItemParent(two, two); hasItemParent(three, three); hasItemParent(four, four); hasItemParent(one, five); hasItemParent(two, six); hasItemParent(three, seven); hasItemParent(four, eight); }
Jul 16 2015
Also checkout inout functions: http://dlang.org/function.html#inout-functions
Jul 16 2015
On Thursday, 16 July 2015 at 18:41:47 UTC, Gary Willoughby wrote:bool hasItemParent(A, B)(A itemId, B parentId) if (isSomeString!(A) && (isSomeString!(B) || isArray!(B) && isSomeString!(ElementType!(B))))Thank you ! I completely missed isSomeString. I think the definition can be safely shortened to: bool hasItemParent(T)(const(char)[] itemId, T parentId) if (isSomeString!T || isSomeString!(ElementType!T)) Minor flaw, as it is the function also accepts wchar[] and dchar[] that break the compilation because I do comparisons with char[].
Jul 16 2015
After a thorough reading of the documentation I found an even simpler solution: bool hasItemParent(T)(const(char)[] itemId, T parentId) if (is(T : const(char)[]) || is(T : const(char[])[])) { ... } Now it accepts all these: char[], const(char)[], immutable(char)[], char[][], const(char)[][] ,immutable(char)[][] but not their wchar and dchar counterparts.
Jul 16 2015