| Thread overview | |||||||||
|---|---|---|---|---|---|---|---|---|---|
|
May 02, 2008 Static strings in templates | ||||
|---|---|---|---|---|
| ||||
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 Re: Static strings in templates | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Janice Caron | 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 Re: Static strings in templates | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Leonard Dahlmann | Leonard Dahlmann wrote:
> 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)
>
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. ^^
--downs
| |||
May 02, 2008 Re: Static strings in templates | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Janice Caron | 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 Re: Static strings in templates | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Janice Caron | 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 Re: Static strings in templates | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | == Quote from Sean Kelly (sean@invisibleduck.org)'s article
> Janice Caron wrote:
> > 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.
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.
Sean
| |||
May 02, 2008 Re: Static strings in templates | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Janice Caron | "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 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 | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply