Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 20, 2013 Can't use variadic arguments to functions that use templates | ||||
---|---|---|---|---|
| ||||
variadic parameters are suppose to make life easier but it seems those don't work with templates. template A(int L) { ... } void foo(T)(string s, T t...) { A!(t.length); } gives error t can't be read at compile time. I understand in general why this works BUT I will only ever use foo where the number of arguments are known at compile time. Therefor to get the code to work I have to revert back to the old way of overloading foo many times to emulate variadic parameters. Essentially all I want to do is to use foo like foo("a", "b", "c", 'd', s, ...) but the number of arguments is fixed at compile time(almost all arguments are, aren't they?). Here is a challenge: Write a function that accepts any number of string or character variables or literals and returns the concatenates them efficiently as possible(as efficient as fixed arguments). e.g., foo1(string s) { return s; } foo2(string s1, string s2) { return s1~s2; } etc... if we had compile time variadic parameters, we could do something like foo(T t$...) { return mixin(concat!t); } where concat produces the string t[0]~t[1]~t[2]... which produces the same code as the overloaded case, but must simpler. I don't think this is possible because there is no static version of variadic arguments, i.e., one who's length is always known at compile time. |
July 20, 2013 Re: Can't use variadic arguments to functions that use templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | JS:
> variadic parameters are suppose to make life easier but it seems those don't work with templates.
>
> template A(int L) { ... }
>
> void foo(T)(string s, T t...)
> {
> A!(t.length);
>
> }
Try this:
template A(size_t L) {
enum A = L;
}
void foo(T...)(string s, T t) {
auto n = A!(t.length);
}
void main() {
foo("x", 1, 2);
}
Bye,
bearophile
|
July 20, 2013 Re: Can't use variadic arguments to functions that use templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Saturday, 20 July 2013 at 17:39:59 UTC, bearophile wrote:
> JS:
>
>> variadic parameters are suppose to make life easier but it seems those don't work with templates.
>>
>> template A(int L) { ... }
>>
>> void foo(T)(string s, T t...)
>> {
>> A!(t.length);
>>
>> }
>
> Try this:
>
>
> template A(size_t L) {
> enum A = L;
> }
>
> void foo(T...)(string s, T t) {
> auto n = A!(t.length);
> }
>
> void main() {
> foo("x", 1, 2);
> }
>
>
> Bye,
> bearophile
;/ I could have swore I tried that ;/
Thanks though! ;)
|
July 20, 2013 Re: Can't use variadic arguments to functions that use templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Saturday, 20 July 2013 at 17:39:59 UTC, bearophile wrote:
> JS:
>
>> variadic parameters are suppose to make life easier but it seems those don't work with templates.
>>
>> template A(int L) { ... }
>>
>> void foo(T)(string s, T t...)
>> {
>> A!(t.length);
>>
>> }
>
> Try this:
>
>
> template A(size_t L) {
> enum A = L;
> }
>
> void foo(T...)(string s, T t) {
> auto n = A!(t.length);
> }
>
> void main() {
> foo("x", 1, 2);
> }
>
>
> Bye,
> bearophile
is there any way to pass t directly to A?
template A(T...) doesn't seem work nor does using an alias. (or at least, when I try to foreach over it, it doesn't work).
|
July 20, 2013 Re: Can't use variadic arguments to functions that use templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | On Saturday, 20 July 2013 at 18:27:23 UTC, JS wrote:
> is there any way to pass t directly to A?
>
> template A(T...) doesn't seem work nor does using an alias. (or at least, when I try to foreach over it, it doesn't work).
template A(size_t L) {
enum A = L;
}
template B(T...) {
void B(T b) {
import std.stdio;
foreach(Type; T) {
pragma(msg, Type.stringof);
}
foreach(v; b) {
writeln(v);
}
}}
void foo(T...)(string s, T t) {
auto n = A!(t.length);
B(t);// t is runtime information
// T is compile time information
}
void main() {
foo("x", 1, 2);
}
|
July 21, 2013 Re: Can't use variadic arguments to functions that use templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jesse Phillips | On Saturday, 20 July 2013 at 18:57:18 UTC, Jesse Phillips wrote:
> On Saturday, 20 July 2013 at 18:27:23 UTC, JS wrote:
>> is there any way to pass t directly to A?
>>
>> template A(T...) doesn't seem work nor does using an alias. (or at least, when I try to foreach over it, it doesn't work).
>
> template A(size_t L) {
> enum A = L;
> }
>
> template B(T...) {
> void B(T b) {
> import std.stdio;
> foreach(Type; T) {
> pragma(msg, Type.stringof);
> }
> foreach(v; b) {
> writeln(v);
> }
> }}
>
> void foo(T...)(string s, T t) {
> auto n = A!(t.length);
> B(t);// t is runtime information
> // T is compile time information
> }
>
> void main() {
> foo("x", 1, 2);
> }
I know I tried that but:
import std.cstream, std.stdio;
template B(T...) {
string B(T b) {
string s;
foreach(Type; T) pragma(msg, Type.stringof);
foreach(v; b) s ~= v.stringof;
return s;
}
}
void foo(T...)(T t)
{
pragma(msg, B(t));
}
void main() {
foo("x", "a", "b");
din.getc();
}
does work. I need to have B generate compile time code so it is efficient. Your method calls an actual function at runtime so it is nearly as fast as it can be.
|
July 22, 2013 Re: Can't use variadic arguments to functions that use templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | On Sunday, 21 July 2013 at 07:22:08 UTC, JS wrote:
> void foo(T...)(T t)
> {
> pragma(msg, B(t));
> }
>
> void main() {
> foo("x", "a", "b");
> din.getc();
> }
>
>
> does work. I need to have B generate compile time code so it is efficient. Your method calls an actual function at runtime so it is nearly as fast as it can be.
My method doesn't make any calls, your foo is a called at runtime. There is no way to observe a function at compile time; ctfeWriteln does not exist.
Also don't stringof variable v (I assume you want the value and not the symbol concatenated.
template B(T...) {
string B(T b) {
string s;
foreach(Type; T) pragma(msg, Type.stringof);
foreach(v; b) s ~= v;
return s;
}
}
string foo(T...)(T t)
{
return B(t);
}
void main() {
enum forced = foo("x", "a", "b");
pragma(msg, forced);
din.getc();
}
|
July 23, 2013 Re: Can't use variadic arguments to functions that use templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jesse Phillips | On Monday, 22 July 2013 at 16:48:56 UTC, Jesse Phillips wrote:
> On Sunday, 21 July 2013 at 07:22:08 UTC, JS wrote:
>> void foo(T...)(T t)
>> {
>> pragma(msg, B(t));
>> }
>>
>> void main() {
>> foo("x", "a", "b");
>> din.getc();
>> }
>>
>>
>> does work. I need to have B generate compile time code so it is efficient. Your method calls an actual function at runtime so it is nearly as fast as it can be.
>
> My method doesn't make any calls, your foo is a called at runtime. There is no way to observe a function at compile time; ctfeWriteln does not exist.
>
> Also don't stringof variable v (I assume you want the value and not the symbol concatenated.
>
> template B(T...) {
> string B(T b) {
> string s;
> foreach(Type; T) pragma(msg, Type.stringof);
> foreach(v; b) s ~= v;
> return s;
> }
> }
>
> string foo(T...)(T t)
> {
> return B(t);
> }
>
> void main() {
> enum forced = foo("x", "a", "b");
> pragma(msg, forced);
> din.getc();
> }
I don't think you understand(or I've already got confused)...
I'm trying to use B has a mixin(I don't think I made this clear). I can't use it as a normal function. e.g., I can't seem to do mixin(B(t)). If I could, this would definitely solve my problem. Here is a real world example:
template VariadicLoop(T...)
{
pragma(msg, T);
string VariadicLoop(T t)
{
string s;
foreach(k; T)
s ~= k.stringof;
foreach(v; t)
s ~= v;
return s;
}
//enum tVariadicLoop = eval();
//pragma(msg, tVariadicLoop);
}
string join(T...)(string delim, T t)
{
return mixin(VariadicLoop(t));
}
VariadicLoop should join the strings passed to join(producing whatever code is necessary to do this efficiently.
e.g.,
join(",", "a", s) should result in the code for join:
{
return "a"~","~s; // s maybe t[1] or something
}
This is the most efficient way to join rather than using a foreach over an array of strings or something or another. (VariadicLoop could handle string[]'s and insert the appropriate code to join them)
The goal I'm trying to solve is efficiently deal with variadic arguments that are compile time calculable along with mixing in the runtime aspect. Basically: get the compiler to do all the work it can before having it done at runtime. if we are passing string literals to join then they can be joined at compile time. If we are passing a combination of string literals, string variables, and string arrays then we deal with each part efficiently as possible.
|
July 23, 2013 Re: Can't use variadic arguments to functions that use templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | On Tuesday, 23 July 2013 at 14:03:01 UTC, JS wrote:
> I don't think you understand(or I've already got confused)...
>
> I'm trying to use B has a mixin(I don't think I made this clear). I can't use it as a normal function. e.g., I can't seem to do mixin(B(t)). If I could, this would definitely solve my problem.
I'll stick with the reduced example, maybe you can apply it to the real world:
template B(T...) {
string B(T b) {
string s;
foreach(i, Type; T)
s ~= Type.stringof ~ " " ~ b[i] ~ ";\n";
return s;
}
}
void main() {
enum forced = B("x", "a", "b");
pragma(msg, forced);
mixin(forced);
}
|
July 23, 2013 Re: Can't use variadic arguments to functions that use templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jesse Phillips | On Tuesday, 23 July 2013 at 16:15:03 UTC, Jesse Phillips wrote:
> On Tuesday, 23 July 2013 at 14:03:01 UTC, JS wrote:
>> I don't think you understand(or I've already got confused)...
>>
>> I'm trying to use B has a mixin(I don't think I made this clear). I can't use it as a normal function. e.g., I can't seem to do mixin(B(t)). If I could, this would definitely solve my problem.
>
> I'll stick with the reduced example, maybe you can apply it to the real world:
>
> template B(T...) {
> string B(T b) {
> string s;
> foreach(i, Type; T)
> s ~= Type.stringof ~ " " ~ b[i] ~ ";\n";
> return s;
> }
> }
>
> void main() {
> enum forced = B("x", "a", "b");
> pragma(msg, forced);
> mixin(forced);
> }
What good does that do?
What if I want to use a run-time variable in the mix?
|
Copyright © 1999-2021 by the D Language Foundation