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
↑ ↓←→ Leonard Dahlmann <leo.dahlmann gmail.com> writes:
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)
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
↑↓← → Christopher Wright <dhasenan gmail.com> writes:
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");
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
↑ ↓ ← → Sean Kelly <sean invisibleduck.org> writes:
== 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?
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
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