www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - template with more than one tuple parameter

reply "Zhenya" <zheny list.ru> writes:
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
Jul 28 2012
next sibling parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
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
Jul 28 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
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 )
Jul 29 2012
prev sibling next sibling parent "Zhenya" <zheny list.ru> writes:
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.
Jul 28 2012
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
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
Jul 28 2012
prev sibling next sibling parent "Zhenya" <zheny list.ru> writes:
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/
Jul 28 2012
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
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.
Jul 29 2012
prev sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
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.

 with(Test!(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.

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
Jul 29 2012