View mode: basic / threaded / horizontal-split · Log in · Help
July 28, 2012
template with more than one tuple parameter
Why do not D allow templates with more than one tuple
parameters,at the
same time that C++11 support it:

namespace
{
template <class R,unsigned int N>
struct Apply_Helper
{
	template<typename F, typename... ArgsT, typename... Args>
	static R apply(const F& f, const std::tuple<ArgsT...>& t,
Args&... args) {
	return Apply_Helper<R,N-1>::apply(f, t, std::get<N-1>(t),
args...);
	}
};

template <class R>
struct Apply_Helper<R,0>
{
	template<typename F, typename... ArgsT, typename... Args>
	static R apply(const F& f, const std::tuple<ArgsT...>&, Args&...
args) {
		return f(args...);
	}
};

template <typename R, typename... ArgsT>
R apply(const std::function<R(ArgsT...)>& f,
std::tuple<ArgsT...>& t)
{
	return Apply_Helper<R,sizeof...(ArgsT)>::apply(f, t);
}
this code compiles in gcc 4.6.1
July 28, 2012
Re: template with more than one tuple parameter
On Sat, 28 Jul 2012 18:17:14 +0200, Zhenya <zheny@list.ru> wrote:

> Why do not D allow templates with more than one tuple
> parameters,at the
> same time that C++11 support it:

Well, Walter implemented type tuples with automatic flattening,
back when dinosaurs roamed the earth (we now help people who have
questions). We've lived with that decision since then, and though
there are times when a non-flattening system would have been nice,
it's easy enough to work around:

template NonFlatteningTuple( T... ) {
    alias T types;
}

template Foo( T, U )  {
    // Do things with T.types and U.types here
}

Foo!( NonFlatteningTuple!(int, float), NonFlatteningTuple!() );

-- 
Simen
July 28, 2012
Re: template with more than one tuple parameter
On Saturday, 28 July 2012 at 16:47:48 UTC, Simen Kjaeraas wrote:
> On Sat, 28 Jul 2012 18:17:14 +0200, Zhenya <zheny@list.ru> 
> wrote:
>
>> Why do not D allow templates with more than one tuple
>> parameters,at the
>> same time that C++11 support it:
>
> Well, Walter implemented type tuples with automatic flattening,
> back when dinosaurs roamed the earth (we now help people who 
> have
> questions). We've lived with that decision since then, and 
> though
> there are times when a non-flattening system would have been 
> nice,
> it's easy enough to work around:
>
> template NonFlatteningTuple( T... ) {
>     alias T types;
> }
>
> template Foo( T, U )  {
>     // Do things with T.types and U.types here
> }
>
> Foo!( NonFlatteningTuple!(int, float), NonFlatteningTuple!() );

But function template can deduce types without explicit 
instansiation,regular template can't.
July 28, 2012
Re: template with more than one tuple parameter
On Sat, 28 Jul 2012 19:08:55 +0200, Zhenya <zheny@list.ru> wrote:

> But function template can deduce types without explicit  
> instansiation,regular template can't.

Ah, yes. I hadn't quite noticed that part. There are still
solutions, but I agree it's nowhere near as nice:

void foo( T, U )( T t, U u ) {
    static if ( is( T _ = NonFlatteningTuple!Args1, Args1... )
        && is( U _ = NonFlatteningTuple!Args2, Args2... ) {
        // Function body
    }
}

-- 
Simen
July 28, 2012
Re: template with more than one tuple parameter
On Saturday, 28 July 2012 at 17:28:21 UTC, Simen Kjaeraas wrote:
> On Sat, 28 Jul 2012 19:08:55 +0200, Zhenya <zheny@list.ru> 
> wrote:
>
>> But function template can deduce types without explicit 
>> instansiation,regular template can't.
>
> Ah, yes. I hadn't quite noticed that part. There are still
> solutions, but I agree it's nowhere near as nice:
>
> void foo( T, U )( T t, U u ) {
>     static if ( is( T _ = NonFlatteningTuple!Args1, Args1... )
>         && is( U _ = NonFlatteningTuple!Args2, Args2... ) {
>         // Function body
>     }
> }

Thank you,understood/
July 29, 2012
Re: template with more than one tuple parameter
On 07/28/2012 06:17 PM, Zhenya wrote:
> Why do not D allow templates with more than one tuple
> parameters,at the same time that C++11 support it:
>

This is a gratuitous restriction. They will be supported at some point.
July 29, 2012
Re: template with more than one tuple parameter
On 07/28/2012 06:47 PM, Simen Kjaeraas wrote:
> On Sat, 28 Jul 2012 18:17:14 +0200, Zhenya <zheny@list.ru> wrote:
>
>> Why do not D allow templates with more than one tuple
>> parameters,at the
>> same time that C++11 support it:
>
> Well, Walter implemented type tuples with automatic flattening,

The lack of multiple tuple parameters is not caused by automatic
flattening.

However, if they are introduced, the respective templates may only
ever be instantiated by IFTI.

To fix this, there would maybe need to be a special syntax to separate
the tuple parameters in an explicit instantiation, eg.

template Seq(T...){ alias T Seq; }

template Test(T..., S...){ alias T A; alias S B; }

with(Test!(int,double,float)){
    static assert(is(A==Seq!(int,double,float)));
    static assert(is(B==Seq!()));
}

with(Test!(int,double,,float)){
    static assert(is(A==Seq!(int,double)));
    static assert(is(B==Seq!(float)));
}

with(Test!(,int,double,float)){
    static assert(is(A==Seq!()));
    static assert(is(B==Seq!(int,double,float)));
}

Of course, that feels a little bolt-on. The alternative would be to
accept that templates with multiple tuple parameters cannot be
instantiated explicitly.


( If we want arbitrary tuple nesting, the notation could be
generalized, eg like this:

Seq!(Seq!(int,double)); // flattened 2-element tuple
Seq!(int,double,,); // 1-element tuple of 2-element tuple
Seq!(int,double,,,); // 1-element tuple of 1-element tuple of 2-element 
tuple
Seq!(int,double,,int,double); // 2-element tuple of 2-element tuples
 )
July 29, 2012
Re: template with more than one tuple parameter
On Sun, 29 Jul 2012 16:13:03 +0200, Timon Gehr <timon.gehr@gmx.ch> wrote:

> On 07/28/2012 06:47 PM, Simen Kjaeraas wrote:
>> On Sat, 28 Jul 2012 18:17:14 +0200, Zhenya <zheny@list.ru> wrote:
>>
>>> Why do not D allow templates with more than one tuple
>>> parameters,at the
>>> same time that C++11 support it:
>>
>> Well, Walter implemented type tuples with automatic flattening,
>
> The lack of multiple tuple parameters is not caused by automatic
> flattening.
>
> However, if they are introduced, the respective templates may only
> ever be instantiated by IFTI.
>
> To fix this, there would maybe need to be a special syntax to separate
> the tuple parameters in an explicit instantiation, eg.
[snip]
> with(Test!(int,double,,float)){
[snip]
> Of course, that feels a little bolt-on. The alternative would be to
> accept that templates with multiple tuple parameters cannot be
> instantiated explicitly.

Indeed it does. We would do well to adopt another symbol than the comma,
I think. I thought for a moment foo!((int, float), (string, char)) could
work, as the comma operator is not defined to work on types. THe problem
appears when one tries to do the same with values: foo!((2,3), (4,5))
would be interpreted as foo!(3,5). Conceivably, one could simply allow
this syntax for type tuples.

Anyway, what other syntaxes do we have with a comma-separated list
and something else? Oh, foreach.

foreach (i, e; range) {}

foo!(int, float; string, char);

That's clearer, I think. And probably the best we get without breaking
other syntaxen.


-- 
Simen
Top | Discussion index | About this forum | D home