digitalmars.D - Static strings in templates
- Janice Caron (20/20) May 02 2008 I don't know if this is a bug or not. Someone please help me out.
- Leonard Dahlmann (6/34) May 02 2008 I think a workaround is to use downs' Unstatic template.
- downs (5/44) May 02 2008 A better way may be to accept _any_ parameter, as in, int foo(T...)(T st...
- Christopher Wright (6/14) May 02 2008 I'd call it a compiler bug since static arrays are, as you say,
- Sean Kelly (18/45) May 02 2008 I think this should work:
- Sean Kelly (7/19) May 02 2008 Scratch that. In D 2.0, array literals could be automatically passed as
- Steven Schveighoffer (7/27) May 02 2008 I think the workaround is to do foo("abcde"[], "fg");
I don't know if this is a bug or not. Someone please help me out. Here's the deal. Suppose I declare: int foo(T)(T s, T t) with the expectation that the template will be passed a couple of strings, wstrings or dstring. All works fine if I do string s; string t; int n = foo(s,t); However, the template can't be instantiated with int n = foo("abcde","fg"); because the type of the first argument is invariant(char)[5u], and the type of the second argument is invariant(char)[2u], and the compiler can't figure out that both can (and should) be implicitly cast to invariant(char)[]. It occurs to me that even with only a single parameter, passing string literals to templated string function will lead to a lot of template bloat, if the template always considers the argument type to be invariant(char)[N] (for some N), as opposed to simply invariant(char)[]. Is this a bug? Can anything be done about this? Is there a workaround?
May 02 2008
Janice Caron Wrote:I don't know if this is a bug or not. Someone please help me out. Here's the deal. Suppose I declare: int foo(T)(T s, T t) with the expectation that the template will be passed a couple of strings, wstrings or dstring. All works fine if I do string s; string t; int n = foo(s,t); However, the template can't be instantiated with int n = foo("abcde","fg"); because the type of the first argument is invariant(char)[5u], and the type of the second argument is invariant(char)[2u], and the compiler can't figure out that both can (and should) be implicitly cast to invariant(char)[]. It occurs to me that even with only a single parameter, passing string literals to templated string function will lead to a lot of template bloat, if the template always considers the argument type to be invariant(char)[N] (for some N), as opposed to simply invariant(char)[]. Is this a bug? Can anything be done about this? Is there a workaround?I think a workaround is to use downs' Unstatic template. Given a static array type, it returns the corresponding dynamic array type. template Unstatic(T) { alias T Unstatic; } template Unstatic(T : T[]) { alias T[] Unstatic; } int foo(T)(Unstatic!(T) s, Unstatic!(T) t)
May 02 2008
Leonard Dahlmann wrote:Janice Caron Wrote:A better way may be to accept _any_ parameter, as in, int foo(T...)(T stuff); Then check if is(typeof(stuff[0][]) == typeof(stuff[1][])), else static assert(false, "Parameters don't expose full slices of the same type!"); Using unstatic probably breaks ifti. Although, I haven't tested it. ^^ --downsI don't know if this is a bug or not. Someone please help me out. Here's the deal. Suppose I declare: int foo(T)(T s, T t) with the expectation that the template will be passed a couple of strings, wstrings or dstring. All works fine if I do string s; string t; int n = foo(s,t); However, the template can't be instantiated with int n = foo("abcde","fg"); because the type of the first argument is invariant(char)[5u], and the type of the second argument is invariant(char)[2u], and the compiler can't figure out that both can (and should) be implicitly cast to invariant(char)[]. It occurs to me that even with only a single parameter, passing string literals to templated string function will lead to a lot of template bloat, if the template always considers the argument type to be invariant(char)[N] (for some N), as opposed to simply invariant(char)[]. Is this a bug? Can anything be done about this? Is there a workaround?I think a workaround is to use downs' Unstatic template. Given a static array type, it returns the corresponding dynamic array type. template Unstatic(T) { alias T Unstatic; } template Unstatic(T : T[]) { alias T[] Unstatic; } int foo(T)(Unstatic!(T) s, Unstatic!(T) t)
May 02 2008
Janice Caron wrote: <snip>However, the template can't be instantiated with int n = foo("abcde","fg"); because the type of the first argument is invariant(char)[5u], and the type of the second argument is invariant(char)[2u], and the compiler can't figure out that both can (and should) be implicitly cast to invariant(char)[].I'd call it a compiler bug since static arrays are, as you say, implicitly convertible to dynamic ones. Of course, you could just call it with: int n = foo("abcde"[], "fg");
May 02 2008
Janice Caron wrote:I don't know if this is a bug or not. Someone please help me out. Here's the deal. Suppose I declare: int foo(T)(T s, T t) with the expectation that the template will be passed a couple of strings, wstrings or dstring. All works fine if I do string s; string t; int n = foo(s,t); However, the template can't be instantiated with int n = foo("abcde","fg"); because the type of the first argument is invariant(char)[5u], and the type of the second argument is invariant(char)[2u], and the compiler can't figure out that both can (and should) be implicitly cast to invariant(char)[].I think this should work: int foo(T)( T[] s, T[] t ); If you want it to accept types other than arrays, however, then things get a bit more complicated: int foo(T,U)( T s, U t ) { static if( isStaticArray!(T) || isStaticArray!(U) ) return foo_!(ElemTypeOf!(T)[])( s, t ); else return foo_!(T)( s, t ); } int foo_(T)( T s, T t );It occurs to me that even with only a single parameter, passing string literals to templated string function will lead to a lot of template bloat, if the template always considers the argument type to be invariant(char)[N] (for some N), as opposed to simply invariant(char)[]. Is this a bug? Can anything be done about this? Is there a workaround?It's not a bug, though it would be nice if there were some way to force parameters to dynamic arrays a bit easier. Perhaps if the parameter were 'const', 'invariant', or 'in' it could be done automatically, since the length restriction is unnecessary in that case. Sean
May 02 2008
== Quote from Sean Kelly (sean invisibleduck.org)'s articleJanice Caron wrote:Scratch that. In D 2.0, array literals could be automatically passed as invariant(T)[], since that will produce the correct behavior in each case. Static arrays could be passed as dynamic arrays in cases where the parameter they are passed to is not out or inout. This latter bit is somewhat of a special case though, and I abhor special cases. SeanIt occurs to me that even with only a single parameter, passing string literals to templated string function will lead to a lot of template bloat, if the template always considers the argument type to be invariant(char)[N] (for some N), as opposed to simply invariant(char)[]. Is this a bug? Can anything be done about this? Is there a workaround?It's not a bug, though it would be nice if there were some way to force parameters to dynamic arrays a bit easier. Perhaps if the parameter were 'const', 'invariant', or 'in' it could be done automatically, since the length restriction is unnecessary in that case.
May 02 2008
"Janice Caron" wroteI don't know if this is a bug or not. Someone please help me out. Here's the deal. Suppose I declare: int foo(T)(T s, T t) with the expectation that the template will be passed a couple of strings, wstrings or dstring. All works fine if I do string s; string t; int n = foo(s,t); However, the template can't be instantiated with int n = foo("abcde","fg"); because the type of the first argument is invariant(char)[5u], and the type of the second argument is invariant(char)[2u], and the compiler can't figure out that both can (and should) be implicitly cast to invariant(char)[]. It occurs to me that even with only a single parameter, passing string literals to templated string function will lead to a lot of template bloat, if the template always considers the argument type to be invariant(char)[N] (for some N), as opposed to simply invariant(char)[]. Is this a bug? Can anything be done about this? Is there a workaround?I think the workaround is to do foo("abcde"[], "fg"); But I have logged a bug for something similar: http://d.puremagic.com/issues/show_bug.cgi?id=1817 I think if the compiler template generation always generated template code for X[] instead of X[5], it would fix both our problems. -Steve
May 02 2008