Thread overview
Heterogeneous Variadic Arguments with Other Arguments
Jul 14, 2019
harakim
Jul 14, 2019
evilrat
Jul 14, 2019
harakim
July 14, 2019
I wanted to do this:
package int serialize(byte[] destination, int offset, T...)(T values)
{	
	static foreach (i, value; values)
	{
		*cast(T[i] *)(destination.ptr + offset) = value;
		offset += typeid(T[i]).tsize();
	}
	
	return offset;
}

But I got this error:
main.d(8): Error: template main.serialize cannot deduce function from argument types !()(byte[], int, byte, int), candidates are:
main.d(20):        main.serialize(byte[] destination, int offset, T...)(T values)

Eventually, I assumed that you couldn't do heterogeneous arguments with other arguments first.

I was able to do this and it works:
package int serialize(T...)(T values)
{
	static assert(values.length >= 2);

	auto ptr = (cast(byte[])values[0]).ptr;
	
	int offset = cast(int)values[1];

	static foreach (i, value; values)
	{
		static if (i > 1)
		{
			*cast(T[i] *)(ptr + offset) = value;
			offset += typeid(T[i]).tsize();
		}
	}
	
	return offset;
}

That is obviously a lot uglier. Can you have a function with non-variadic arguments followed by heterogeneous variadic arguments?
July 14, 2019
On Sunday, 14 July 2019 at 03:51:14 UTC, harakim wrote:
> I wanted to do this:
> package int serialize(byte[] destination, int offset, T...)(T values)
> ....

Can't really tell what's going on without call site and what do you exactly mean by "heterogeneous arguments with other arguments", but this thing is syntax error. You declared a template here, and template parameters (compile-time parameters) must come first.

   int serialize(T...)(byte[] destination, int offset, T values)

This is the case if you wanted to pass that buffer at runtime, not sure if you can do this with CT parameters, though it shouldn't prevent you from forcing CTFE evaluation by assigning result to another CT parameter or enum.


But if by "other arguments" you mean passing different types there is untyped variadics with a bit different behavior(see [1])


[1] https://dlang.org/spec/function.html#d_style_variadic_functions


July 14, 2019
On Sunday, 14 July 2019 at 06:05:13 UTC, evilrat wrote:
> On Sunday, 14 July 2019 at 03:51:14 UTC, harakim wrote:
>> I wanted to do this:
>> package int serialize(byte[] destination, int offset, T...)(T values)
>> ....
>
> Can't really tell what's going on without call site and what do you exactly mean by "heterogeneous arguments with other arguments", but this thing is syntax error. You declared a template here, and template parameters (compile-time parameters) must come first.
>
>    int serialize(T...)(byte[] destination, int offset, T values)
>
> This is the case if you wanted to pass that buffer at runtime, not sure if you can do this with CT parameters, though it shouldn't prevent you from forcing CTFE evaluation by assigning result to another CT parameter or enum.
>
>
> But if by "other arguments" you mean passing different types there is untyped variadics with a bit different behavior(see [1])
>
>
> [1] https://dlang.org/spec/function.html#d_style_variadic_functions

Thanks. That answered my question. I was hoping to do this:
int serialize(T...)(byte[] destination, int offset, T values)

And now I understand a lot more about variadic functions and type arguments.