Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 15, 2015 Template function that accept strings and array of strings | ||||
---|---|---|---|---|
| ||||
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 ? |
July 15, 2015 Re: Template function that accept strings and array of strings | ||||
---|---|---|---|---|
| ||||
Posted in reply to badlink | 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.
|
July 15, 2015 Re: Template function that accept strings and array of strings | ||||
---|---|---|---|---|
| ||||
Posted in reply to badlink | 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)))
|
July 16, 2015 Re: Template function that accept strings and array of strings | ||||
---|---|---|---|---|
| ||||
Posted in reply to badlink | 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 |
July 16, 2015 Re: Template function that accept strings and array of strings | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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) ? |
July 16, 2015 Re: Template function that accept strings and array of strings | ||||
---|---|---|---|---|
| ||||
Posted in reply to badlink | 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); } |
July 16, 2015 Re: Template function that accept strings and array of strings | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gary Willoughby | Also checkout inout functions: http://dlang.org/function.html#inout-functions |
July 16, 2015 Re: Template function that accept strings and array of strings | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gary Willoughby | 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[].
|
July 16, 2015 Re: Template function that accept strings and array of strings | ||||
---|---|---|---|---|
| ||||
Posted in reply to badlink | 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. |
July 17, 2015 Re: Template function that accept strings and array of strings | ||||
---|---|---|---|---|
| ||||
Posted in reply to badlink | 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 |
Copyright © 1999-2021 by the D Language Foundation