Topic: Partial application of template parameters
Author: Morwenn <morwenn29@gmail.com>
Date: Sun, 6 Dec 2015 16:11:50 -0800 (PST)
Raw View
------=_Part_4284_1367811567.1449447110620
Content-Type: multipart/alternative;
boundary="----=_Part_4285_838106604.1449447110621"
------=_Part_4285_838106604.1449447110621
Content-Type: text/plain; charset=UTF-8
To be honest, that proposal is a bit fancy. It's the resolution to a
problem that I did not managed to solve. The alternative solution is
template template alias.
Basically, I am building a sorting algorithms library, with function
objects known as sorters; these sorters have an overloaded operator() and
implementing
different sorting algorithms. However, some algorithms use a temporary
buffer and the performance of the algorithm may greatly depend on how this
buffer
was allocated. Here is an example of what a buffered algorithm would look
like:
template<template<typename T> class Buffer>
struct sorter
{
template<typename Iterator, typename Compare>
void operator()(Iterator first, Iterator last, Compare comp)
{
using value_type = typename
std::iterator_traits<Iterator>::value_type;
// allocate the buffer
Buffer<value_type> buffer;
// Sort the range...
}
};
Consider that I want a sorter that will always statically allocate exactly
512 elements. I could write the buffer class like this:
template<std::size_t N, typename T>
struct buffer
{
T array[N];
};
I wish that the following code was valid:
using my_sorter = sorter<buffer<512>>;
The idea alone is pretty clear: buffer<512> is actually a template that
accepts a type parameter that can be given later. While a user can still
write
template<typename T >using buffer_512 = buffer<512, T>, it's highly
redundant when you want to create many types with different
buffer sizes. The problem arises from the fact that the two template
parameters are actually known at different times. To solve the problem in
an elegant
manner, we either need to add partial template parameter application in the
language (as illutrated in the example above). I couldn't think of any other
elegant way to solve the problem without requiring users to write
additional template boilerplate.
Any thoughts about the idea?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_4285_838106604.1449447110621
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">To be honest, that proposal is a bit fancy. It's the r=
esolution to a problem that I did not managed to solve. The alternative sol=
ution is template template alias.<br>Basically, I am building a sorting alg=
orithms library, with function objects known as sorters; these sorters have=
an overloaded operator() and implementing<br>different sorting algorithms.=
However, some algorithms use a temporary buffer and the performance of the=
algorithm may greatly depend on how this buffer<br>was allocated. Here is =
an example of what a buffered algorithm would look like:<br><br><div style=
=3D"margin-left: 40px;"><span style=3D"font-family: courier new,monospace;"=
>template<template<typename T> class Buffer><br>struct sorter<b=
r>{<br>=C2=A0=C2=A0=C2=A0 template<typename Iterator, typename Compare&g=
t;<br>=C2=A0=C2=A0=C2=A0 void operator()(Iterator first, Iterator last, Com=
pare comp)<br>=C2=A0=C2=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 using value_type =3D typename std::iterator_traits<Iterator>::=
value_type;<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // allocate t=
he buffer<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Buffer<value_typ=
e> buffer;<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // Sort the=
range...<br>=C2=A0=C2=A0=C2=A0 }<br>};</span><br></div><br>Consider that I=
want a sorter that will always statically allocate exactly 512 elements. I=
could write the buffer class like this:<br><br><div style=3D"margin-left: =
40px;"><span style=3D"font-family: courier new,monospace;">template<std:=
:size_t N, typename T><br>struct buffer<br>{<br>=C2=A0=C2=A0=C2=A0 T arr=
ay[N];<br>};</span><br></div><br>I wish that the following code was valid:<=
br><br><div style=3D"margin-left: 40px;"><span style=3D"font-family: courie=
r new,monospace;">using my_sorter =3D sorter<buffer<512>>;</spa=
n><br></div><br>The idea alone is pretty clear: <span style=3D"font-family:=
courier new,monospace;">buffer<512></span> is actually a template th=
at accepts a type parameter that can be given later. While a user can still=
write<br><span style=3D"font-family: courier new,monospace;">template<t=
ypename T >using buffer_512 =3D buffer<512, T></span>, it's hi=
ghly redundant when you want to create many types with different<br>buffer =
sizes. The problem arises from the fact that the two template parameters ar=
e actually known at different times. To solve the problem in an elegant<br>=
manner, we either need to add partial template parameter application in the=
language (as illutrated in the example above). I couldn't think of any=
other<br>elegant way to solve the problem without requiring users to write=
additional template boilerplate.<br><br>Any thoughts about the idea?<br></=
div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_4285_838106604.1449447110621--
------=_Part_4284_1367811567.1449447110620--
.
Author: "dgutson ." <danielgutson@gmail.com>
Date: Sun, 6 Dec 2015 23:28:29 -0300
Raw View
On Sun, Dec 6, 2015 at 9:11 PM, Morwenn <morwenn29@gmail.com> wrote:
> To be honest, that proposal is a bit fancy. It's the resolution to a prob=
lem
> that I did not managed to solve. The alternative solution is template
> template alias.
> Basically, I am building a sorting algorithms library, with function obje=
cts
> known as sorters; these sorters have an overloaded operator() and
> implementing
> different sorting algorithms. However, some algorithms use a temporary
> buffer and the performance of the algorithm may greatly depend on how thi=
s
> buffer
> was allocated. Here is an example of what a buffered algorithm would look
> like:
>
> template<template<typename T> class Buffer>
> struct sorter
> {
> template<typename Iterator, typename Compare>
> void operator()(Iterator first, Iterator last, Compare comp)
> {
> using value_type =3D typename
> std::iterator_traits<Iterator>::value_type;
>
> // allocate the buffer
> Buffer<value_type> buffer;
>
> // Sort the range...
> }
> };
>
> Consider that I want a sorter that will always statically allocate exactl=
y
> 512 elements. I could write the buffer class like this:
>
> template<std::size_t N, typename T>
> struct buffer
> {
> T array[N];
> };
>
> I wish that the following code was valid:
>
> using my_sorter =3D sorter<buffer<512>>;
I understand the point, but pre-template alias hack works:
template <size_t N>
struct buffer
{
template <class T>
struct Type
{
T array[N];
};
};
template <class T>
using buffer512 =3D buffer<512>::Type<T>;
buffer512<int> b;
>
> The idea alone is pretty clear: buffer<512> is actually a template that
> accepts a type parameter that can be given later. While a user can still
> write
> template<typename T >using buffer_512 =3D buffer<512, T>, it's highly
> redundant when you want to create many types with different
> buffer sizes. The problem arises from the fact that the two template
> parameters are actually known at different times. To solve the problem in=
an
> elegant
> manner, we either need to add partial template parameter application in t=
he
> language (as illutrated in the example above). I couldn't think of any ot=
her
> elegant way to solve the problem without requiring users to write additio=
nal
> template boilerplate.
>
> Any thoughts about the idea?
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
--=20
Who=E2=80=99s got the sweetest disposition?
One guess, that=E2=80=99s who?
Who=E2=80=99d never, ever start an argument?
Who never shows a bit of temperament?
Who's never wrong but always right?
Who'd never dream of starting a fight?
Who get stuck with all the bad luck?
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: "dgutson ." <danielgutson@gmail.com>
Date: Sun, 6 Dec 2015 23:34:26 -0300
Raw View
On Sun, Dec 6, 2015 at 11:28 PM, dgutson . <danielgutson@gmail.com> wrote:
> On Sun, Dec 6, 2015 at 9:11 PM, Morwenn <morwenn29@gmail.com> wrote:
>> To be honest, that proposal is a bit fancy. It's the resolution to a pro=
blem
>> that I did not managed to solve. The alternative solution is template
>> template alias.
>> Basically, I am building a sorting algorithms library, with function obj=
ects
>> known as sorters; these sorters have an overloaded operator() and
>> implementing
>> different sorting algorithms. However, some algorithms use a temporary
>> buffer and the performance of the algorithm may greatly depend on how th=
is
>> buffer
>> was allocated. Here is an example of what a buffered algorithm would loo=
k
>> like:
>>
>> template<template<typename T> class Buffer>
>> struct sorter
>> {
>> template<typename Iterator, typename Compare>
>> void operator()(Iterator first, Iterator last, Compare comp)
>> {
>> using value_type =3D typename
>> std::iterator_traits<Iterator>::value_type;
>>
>> // allocate the buffer
>> Buffer<value_type> buffer;
>>
>> // Sort the range...
>> }
>> };
>>
>> Consider that I want a sorter that will always statically allocate exact=
ly
>> 512 elements. I could write the buffer class like this:
>>
>> template<std::size_t N, typename T>
>> struct buffer
>> {
>> T array[N];
>> };
>>
>> I wish that the following code was valid:
>>
>> using my_sorter =3D sorter<buffer<512>>;
>
> I understand the point, but pre-template alias hack works:
>
> template <size_t N>
> struct buffer
> {
> template <class T>
> struct Type
> {
> T array[N];
> };
> };
>
> template <class T>
> using buffer512 =3D buffer<512>::Type<T>;
>
> buffer512<int> b;
Using your code with my buffer definition, it was actually easier:
using my_sorter =3D sorter<buffer<512>::Type>;
>
>>
>> The idea alone is pretty clear: buffer<512> is actually a template that
>> accepts a type parameter that can be given later. While a user can still
>> write
>> template<typename T >using buffer_512 =3D buffer<512, T>, it's highly
>> redundant when you want to create many types with different
>> buffer sizes. The problem arises from the fact that the two template
>> parameters are actually known at different times. To solve the problem i=
n an
>> elegant
>> manner, we either need to add partial template parameter application in =
the
>> language (as illutrated in the example above). I couldn't think of any o=
ther
>> elegant way to solve the problem without requiring users to write additi=
onal
>> template boilerplate.
>>
>> Any thoughts about the idea?
>>
>> --
>>
>> ---
>> You received this message because you are subscribed to the Google Group=
s
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n
>> email to std-proposals+unsubscribe@isocpp.org.
>> To post to this group, send email to std-proposals@isocpp.org.
>> Visit this group at
>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
>
>
> --
> Who=E2=80=99s got the sweetest disposition?
> One guess, that=E2=80=99s who?
> Who=E2=80=99d never, ever start an argument?
> Who never shows a bit of temperament?
> Who's never wrong but always right?
> Who'd never dream of starting a fight?
> Who get stuck with all the bad luck?
--=20
Who=E2=80=99s got the sweetest disposition?
One guess, that=E2=80=99s who?
Who=E2=80=99d never, ever start an argument?
Who never shows a bit of temperament?
Who's never wrong but always right?
Who'd never dream of starting a fight?
Who get stuck with all the bad luck?
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Mon, 7 Dec 2015 13:19:24 +0100
Raw View
This is a multi-part message in MIME format.
--------------020304000503020007090500
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 07/12/2015 01:11, Morwenn a =C3=A9crit :
> To be honest, that proposal is a bit fancy. It's the resolution to a=20
> problem that I did not managed to solve. The alternative solution is=20
> template template alias.
> Basically, I am building a sorting algorithms library, with function=20
> objects known as sorters; these sorters have an overloaded operator()=20
> and implementing
> different sorting algorithms. However, some algorithms use a temporary=20
> buffer and the performance of the algorithm may greatly depend on how=20
> this buffer
> was allocated. Here is an example of what a buffered algorithm would=20
> look like:
>
> template<template<typename T> class Buffer>
> struct sorter
> {
> template<typename Iterator, typename Compare>
> void operator()(Iterator first, Iterator last, Compare comp)
> {
> using value_type =3D typename=20
> std::iterator_traits<Iterator>::value_type;
>
> // allocate the buffer
> Buffer<value_type> buffer;
>
> // Sort the range...
> }
> };
>
> Consider that I want a sorter that will always statically allocate=20
> exactly 512 elements. I could write the buffer class like this:
>
> template<std::size_t N, typename T>
> struct buffer
> {
> T array[N];
> };
>
> I wish that the following code was valid:
>
> using my_sorter =3D sorter<buffer<512>>;
>
> The idea alone is pretty clear: buffer<512> is actually a template=20
> that accepts a type parameter that can be given later. While a user=20
> can still write
> template<typename T >using buffer_512 =3D buffer<512, T>, it's highly=20
> redundant when you want to create many types with different
> buffer sizes. The problem arises from the fact that the two template=20
> parameters are actually known at different times. To solve the problem=20
> in an elegant
> manner, we either need to add partial template parameter application=20
> in the language (as illutrated in the example above). I couldn't think=20
> of any other
> elegant way to solve the problem without requiring users to write=20
> additional template boilerplate.
>
> Any thoughts about the idea?
>
If your all the parameters of your template are types
template<typename N, typename T>
struct buffer
{
T array[N::value];
};
you could use a lift meta-functions that binds the fist argument to a=20
variadic template so that you could so
using my_sorter =3D sorter<Lift<buffer, int_constant<512>>::template apply>=
;
where
template <template <class...> TC, class T>
struct Lift {
template <class ...Ts>
using apply =3D TC<T, Ts...>;
};
This solution
using my_sorter =3D sorter<lift<buffer, int_constant<512>>::template=
=20
apply>;
has more noise than what you propose
using my_sorter =3D sorter<buffer<512>>;
If your class was defined instead as
template<class BufferFactory>
struct sorter
{
template<typename Iterator, typename Compare>
void operator()(Iterator first, Iterator last, Compare comp)
{
using value_type =3D typename=20
std::iterator_traits<Iterator>::value_type;
Apply<BufferFactory,value_type> buffer;
// ...
}
};
where Apply is defined as
template <class TC, class T>
using Apply =3D TC::template apply<T>;
Then you could use it as
using my_sorter =3D sorter<Lift<buffer, int_constant<512>>>;
This alternative has yet the limitation of been applicable only to=20
templates with types as parameters and has more noise than what you propose=
..
So yes, I believe that something like that will be useful. There are=20
however some interactions that must be studied:
optional parameters:
template<std::size_t N, typename T=3Dint>
struct buffer;
what buffer<42> could be, a template or a type?
variadics templates:
template<typename ...Ts>
struct xxx;
what xxx<42> could be, a template or a type?
Vicente
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--------------020304000503020007090500
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
</head>
<body text=3D"#000000" bgcolor=3D"#FFFFFF">
<div class=3D"moz-cite-prefix">Le 07/12/2015 01:11, Morwenn a =C3=A9cri=
t=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:6f5f7716-3b6a-47f8-a07c-05de416f5533@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">To be honest, that proposal is a bit fancy. It's
the resolution to a problem that I did not managed to solve. The
alternative solution is template template alias.<br>
Basically, I am building a sorting algorithms library, with
function objects known as sorters; these sorters have an
overloaded operator() and implementing<br>
different sorting algorithms. However, some algorithms use a
temporary buffer and the performance of the algorithm may
greatly depend on how this buffer<br>
was allocated. Here is an example of what a buffered algorithm
would look like:<br>
<br>
<div style=3D"margin-left: 40px;"><span style=3D"font-family:
courier new,monospace;">template<template<typename
T> class Buffer><br>
struct sorter<br>
{<br>
=C2=A0=C2=A0=C2=A0 template<typename Iterator, typename Comp=
are><br>
=C2=A0=C2=A0=C2=A0 void operator()(Iterator first, Iterator las=
t, Compare
comp)<br>
=C2=A0=C2=A0=C2=A0 {<br>
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 using value_type =3D=
typename
std::iterator_traits<Iterator>::value_type;<br>
<br>
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // allocate the buff=
er<br>
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Buffer<value_type=
> buffer;<br>
<br>
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // Sort the range...=
<br>
=C2=A0=C2=A0=C2=A0 }<br>
};</span><br>
</div>
<br>
Consider that I want a sorter that will always statically
allocate exactly 512 elements. I could write the buffer class
like this:<br>
<br>
<div style=3D"margin-left: 40px;"><span style=3D"font-family:
courier new,monospace;">template<std::size_t N, typename
T><br>
struct buffer<br>
{<br>
=C2=A0=C2=A0=C2=A0 T array[N];<br>
};</span><br>
</div>
<br>
I wish that the following code was valid:<br>
<br>
<div style=3D"margin-left: 40px;"><span style=3D"font-family:
courier new,monospace;">using my_sorter =3D
sorter<buffer<512>>;</span><br>
</div>
<br>
The idea alone is pretty clear: <span style=3D"font-family:
courier new,monospace;">buffer<512></span> is actually a
template that accepts a type parameter that can be given later.
While a user can still write<br>
<span style=3D"font-family: courier new,monospace;">template<typ=
ename
T >using buffer_512 =3D buffer<512, T></span>, it's
highly redundant when you want to create many types with
different<br>
buffer sizes. The problem arises from the fact that the two
template parameters are actually known at different times. To
solve the problem in an elegant<br>
manner, we either need to add partial template parameter
application in the language (as illutrated in the example
above). I couldn't think of any other<br>
elegant way to solve the problem without requiring users to
write additional template boilerplate.<br>
<br>
Any thoughts about the idea?<br>
</div>
<br>
</blockquote>
If your all the parameters of your template are types<br>
<br>
template<typename N, typename T><br>
struct buffer<br>
{<br>
=C2=A0=C2=A0=C2=A0 T array[N::value];<br>
};<br>
<br>
you could use a lift meta-functions that binds the fist argument to
a variadic template so that you could so<br>
<br>
using my_sorter =3D sorter<Lift<buffer,
int_constant<512>>::template apply>;<br>
<br>
where<br>
<br>
template <template <class...> TC, class T><br>
struct Lift {<br>
=C2=A0=C2=A0=C2=A0 template <class ...Ts><br>
=C2=A0=C2=A0=C2=A0 using apply =3D TC<T, Ts...>;<br>
};<br>
<br>
<br>
This solution<br>
=C2=A0=C2=A0=C2=A0 using my_sorter =3D sorter<lift<buffer,
int_constant<512>>::template apply>;<br>
<br>
has more noise than what you propose<br>
<br>
=C2=A0=C2=A0=C2=A0 using my_sorter =3D sorter<buffer<512>>;=
<br>
<br>
If your class was defined instead as<br>
<br>
template<class BufferFactory><br>
struct sorter<br>
{<br>
=C2=A0=C2=A0=C2=A0 template<typename Iterator, typename Compare><=
br>
=C2=A0=C2=A0=C2=A0 void operator()(Iterator first, Iterator last, Compa=
re comp)<br>
=C2=A0=C2=A0=C2=A0 {<br>
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 using value_type =3D typenam=
e
std::iterator_traits<Iterator>::value_type;<br>
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Apply<BufferFactory,value=
_type> buffer;<br>
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // ...<br>
=C2=A0=C2=A0=C2=A0 }<br>
};<br>
<br>
<br>
where Apply is defined as<br>
<br>
template <class TC, class T><br>
using Apply =3D TC::template apply<T>;<br>
<br>
Then you could use it as<br>
<br>
=C2=A0=C2=A0=C2=A0 using my_sorter =3D sorter<Lift<buffer,
int_constant<512>>>;<br>
<br>
This alternative has yet the limitation of been applicable only to
templates with types as parameters and has more noise than what you
propose.<br>
<br>
So yes, I believe that something like that will be useful. There are
however some interactions that must be studied: <br>
<br>
optional parameters: <br>
<span style=3D"font-family: courier new,monospace;">template<std::si=
ze_t
N, typename T=3Dint><br>
struct buffer;<br>
<br>
what buffer<42> </span><span style=3D"font-family: courier
new,monospace;">could be, a template or a type?<br>
<br>
</span>variadics templates:<br>
<br>
<span style=3D"font-family: courier new,monospace;">template<typenam=
e
...Ts><br>
struct xxx;<br>
<br>
</span><br>
<span style=3D"font-family: courier new,monospace;">what xxx<42>
could be, a template or a type?<br>
</span>
<br>
Vicente<span style=3D"font-family: courier new,monospace;"><br>
</span>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--------------020304000503020007090500--
.
Author: Morwenn <morwenn29@gmail.com>
Date: Mon, 7 Dec 2015 04:28:53 -0800 (PST)
Raw View
------=_Part_118_891547894.1449491333368
Content-Type: multipart/alternative;
boundary="----=_Part_119_1416601695.1449491333368"
------=_Part_119_1416601695.1449491333368
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Yeah, I realized too that it may not play nice with default template=20
parameters. I can't find a satisfying syntax for alias template template=20
either to hand-roll
partial applications without having to write subclasses either. There is=20
probably a small problem to be solved there, but the solutions do not seem=
=20
to be as
obvious as I thought they could be.
Ideally, the nature of xxx<42> could be context-sensitive and be a type if=
=20
passed to a template that requires a type, or a partial template=20
application if passed
to a template that requires a template, but this isn't really satifying=20
either.
Le lundi 7 d=C3=A9cembre 2015 13:19:28 UTC+1, Vicente J. Botet Escriba a =
=C3=A9crit :
>
> Le 07/12/2015 01:11, Morwenn a =C3=A9crit :
>
> To be honest, that proposal is a bit fancy. It's the resolution to a=20
> problem that I did not managed to solve. The alternative solution is=20
> template template alias.
> Basically, I am building a sorting algorithms library, with function=20
> objects known as sorters; these sorters have an overloaded operator() and=
=20
> implementing
> different sorting algorithms. However, some algorithms use a temporary=20
> buffer and the performance of the algorithm may greatly depend on how thi=
s=20
> buffer
> was allocated. Here is an example of what a buffered algorithm would look=
=20
> like:
>
> template<template<typename T> class Buffer>
> struct sorter
> {
> template<typename Iterator, typename Compare>
> void operator()(Iterator first, Iterator last, Compare comp)
> {
> using value_type =3D typename=20
> std::iterator_traits<Iterator>::value_type;
>
> // allocate the buffer
> Buffer<value_type> buffer;
>
> // Sort the range...
> }
> };
>
> Consider that I want a sorter that will always statically allocate exactl=
y=20
> 512 elements. I could write the buffer class like this:
>
> template<std::size_t N, typename T>
> struct buffer
> {
> T array[N];
> };
>
> I wish that the following code was valid:
>
> using my_sorter =3D sorter<buffer<512>>;
>
> The idea alone is pretty clear: buffer<512> is actually a template that=
=20
> accepts a type parameter that can be given later. While a user can still=
=20
> write
> template<typename T >using buffer_512 =3D buffer<512, T>, it's highly=20
> redundant when you want to create many types with different
> buffer sizes. The problem arises from the fact that the two template=20
> parameters are actually known at different times. To solve the problem in=
=20
> an elegant
> manner, we either need to add partial template parameter application in=
=20
> the language (as illutrated in the example above). I couldn't think of an=
y=20
> other
> elegant way to solve the problem without requiring users to write=20
> additional template boilerplate.
>
> Any thoughts about the idea?
>
> If your all the parameters of your template are types
>
> template<typename N, typename T>
> struct buffer
> {
> T array[N::value];
> };
>
> you could use a lift meta-functions that binds the fist argument to a=20
> variadic template so that you could so
>
> using my_sorter =3D sorter<Lift<buffer, int_constant<512>>::template appl=
y>;
>
> where
>
> template <template <class...> TC, class T>
> struct Lift {
> template <class ...Ts>
> using apply =3D TC<T, Ts...>;
> };
>
>
> This solution
> using my_sorter =3D sorter<lift<buffer, int_constant<512>>::template=
=20
> apply>;
>
> has more noise than what you propose
>
> using my_sorter =3D sorter<buffer<512>>;
>
> If your class was defined instead as
>
> template<class BufferFactory>
> struct sorter
> {
> template<typename Iterator, typename Compare>
> void operator()(Iterator first, Iterator last, Compare comp)
> {
> using value_type =3D typename=20
> std::iterator_traits<Iterator>::value_type;
> Apply<BufferFactory,value_type> buffer;
> // ...
> }
> };
>
>
> where Apply is defined as
>
> template <class TC, class T>
> using Apply =3D TC::template apply<T>;
>
> Then you could use it as
>
> using my_sorter =3D sorter<Lift<buffer, int_constant<512>>>;
>
> This alternative has yet the limitation of been applicable only to=20
> templates with types as parameters and has more noise than what you propo=
se.
>
> So yes, I believe that something like that will be useful. There are=20
> however some interactions that must be studied:=20
>
> optional parameters:=20
> template<std::size_t N, typename T=3Dint>
> struct buffer;
>
> what buffer<42> could be, a template or a type?
>
> variadics templates:
>
> template<typename ...Ts>
> struct xxx;
>
>
> what xxx<42> could be, a template or a type?
>
> Vicente
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_119_1416601695.1449491333368
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Yeah, I realized too that it may not play nice with defaul=
t template parameters. I can't find a satisfying syntax for alias templ=
ate template either to hand-roll<br>partial applications without having to =
write subclasses either. There is probably a small problem to be solved the=
re, but the solutions do not seem to be as<br>obvious as I thought they cou=
ld be.<br><br>Ideally, the nature of xxx<42> could be context-sensiti=
ve and be a type if passed to a template that requires a type, or a partial=
template application if passed<br>to a template that requires a template, =
but this isn't really satifying either.<br><br>Le lundi 7 d=C3=A9cembre=
2015 13:19:28 UTC+1, Vicente J. Botet Escriba a =C3=A9crit=C2=A0:<blockquo=
te class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left:=
1px #ccc solid;padding-left: 1ex;">
=20
=20
=20
<div text=3D"#000000" bgcolor=3D"#FFFFFF">
<div>Le 07/12/2015 01:11, Morwenn a =C3=A9crit=C2=A0:<br>
</div>
<blockquote type=3D"cite">
<div dir=3D"ltr">To be honest, that proposal is a bit fancy. It's
the resolution to a problem that I did not managed to solve. The
alternative solution is template template alias.<br>
Basically, I am building a sorting algorithms library, with
function objects known as sorters; these sorters have an
overloaded operator() and implementing<br>
different sorting algorithms. However, some algorithms use a
temporary buffer and the performance of the algorithm may
greatly depend on how this buffer<br>
was allocated. Here is an example of what a buffered algorithm
would look like:<br>
<br>
<div style=3D"margin-left:40px"><span style=3D"font-family:courier =
new,monospace">template<template<typename
T> class Buffer><br>
struct sorter<br>
{<br>
=C2=A0=C2=A0=C2=A0 template<typename Iterator, typename Comp=
are><br>
=C2=A0=C2=A0=C2=A0 void operator()(Iterator first, Iterator las=
t, Compare
comp)<br>
=C2=A0=C2=A0=C2=A0 {<br>
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 using value_type =3D=
typename
std::iterator_traits<Iterator><wbr>::value_type;<br>
<br>
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // allocate the buff=
er<br>
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Buffer<value_type=
> buffer;<br>
<br>
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // Sort the range...=
<br>
=C2=A0=C2=A0=C2=A0 }<br>
};</span><br>
</div>
<br>
Consider that I want a sorter that will always statically
allocate exactly 512 elements. I could write the buffer class
like this:<br>
<br>
<div style=3D"margin-left:40px"><span style=3D"font-family:courier =
new,monospace">template<std::size_t N, typename
T><br>
struct buffer<br>
{<br>
=C2=A0=C2=A0=C2=A0 T array[N];<br>
};</span><br>
</div>
<br>
I wish that the following code was valid:<br>
<br>
<div style=3D"margin-left:40px"><span style=3D"font-family:courier =
new,monospace">using my_sorter =3D
sorter<buffer<512>>;</span><br>
</div>
<br>
The idea alone is pretty clear: <span style=3D"font-family:courier =
new,monospace">buffer<512></span> is actually a
template that accepts a type parameter that can be given later.
While a user can still write<br>
<span style=3D"font-family:courier new,monospace">template<typen=
ame
T >using buffer_512 =3D buffer<512, T></span>, it's
highly redundant when you want to create many types with
different<br>
buffer sizes. The problem arises from the fact that the two
template parameters are actually known at different times. To
solve the problem in an elegant<br>
manner, we either need to add partial template parameter
application in the language (as illutrated in the example
above). I couldn't think of any other<br>
elegant way to solve the problem without requiring users to
write additional template boilerplate.<br>
<br>
Any thoughts about the idea?<br>
</div>
<br>
</blockquote>
If your all the parameters of your template are types<br>
<br>
template<typename N, typename T><br>
struct buffer<br>
{<br>
=C2=A0=C2=A0=C2=A0 T array[N::value];<br>
};<br>
<br>
you could use a lift meta-functions that binds the fist argument to
a variadic template so that you could so<br>
<br>
using my_sorter =3D sorter<Lift<buffer,
int_constant<512>>::template apply>;<br>
<br>
where<br>
<br>
template <template <class...> TC, class T><br>
struct Lift {<br>
=C2=A0=C2=A0=C2=A0 template <class ...Ts><br>
=C2=A0=C2=A0=C2=A0 using apply =3D TC<T, Ts...>;<br>
};<br>
<br>
<br>
This solution<br>
=C2=A0=C2=A0=C2=A0 using my_sorter =3D sorter<lift<buffer,
int_constant<512>>::template apply>;<br>
<br>
has more noise than what you propose<br>
<br>
=C2=A0=C2=A0=C2=A0 using my_sorter =3D sorter<buffer<512>>;=
<br>
<br>
If your class was defined instead as<br>
<br>
template<class BufferFactory><br>
struct sorter<br>
{<br>
=C2=A0=C2=A0=C2=A0 template<typename Iterator, typename Compare><=
br>
=C2=A0=C2=A0=C2=A0 void operator()(Iterator first, Iterator last, Compa=
re comp)<br>
=C2=A0=C2=A0=C2=A0 {<br>
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 using value_type =3D typenam=
e
std::iterator_traits<Iterator><wbr>::value_type;<br>
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Apply<BufferFactory,value=
_<wbr>type> buffer;<br>
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // ...<br>
=C2=A0=C2=A0=C2=A0 }<br>
};<br>
<br>
<br>
where Apply is defined as<br>
<br>
template <class TC, class T><br>
using Apply =3D TC::template apply<T>;<br>
<br>
Then you could use it as<br>
<br>
=C2=A0=C2=A0=C2=A0 using my_sorter =3D sorter<Lift<buffer,
int_constant<512>>>;<br>
<br>
This alternative has yet the limitation of been applicable only to
templates with types as parameters and has more noise than what you
propose.<br>
<br>
So yes, I believe that something like that will be useful. There are
however some interactions that must be studied: <br>
<br>
optional parameters: <br>
<span style=3D"font-family:courier new,monospace">template<std::size=
_t
N, typename T=3Dint><br>
struct buffer;<br>
<br>
what buffer<42> </span><span style=3D"font-family:courier new,m=
onospace">could be, a template or a type?<br>
<br>
</span>variadics templates:<br>
<br>
<span style=3D"font-family:courier new,monospace">template<typename
...Ts><br>
struct xxx;<br>
<br>
</span><br>
<span style=3D"font-family:courier new,monospace">what xxx<42>
could be, a template or a type?<br>
</span>
<br>
Vicente<span style=3D"font-family:courier new,monospace"><br>
</span>
</div>
</blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_119_1416601695.1449491333368--
------=_Part_118_891547894.1449491333368--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Mon, 7 Dec 2015 19:30:54 +0100
Raw View
Le 07/12/2015 13:28, Morwenn a =C3=A9crit :
> Yeah, I realized too that it may not play nice with default template=20
> parameters. I can't find a satisfying syntax for alias template=20
> template either to hand-roll
> partial applications without having to write subclasses either. There=20
> is probably a small problem to be solved there, but the solutions do=20
> not seem to be as
> obvious as I thought they could be.
>
> Ideally, the nature of xxx<42> could be context-sensitive and be a=20
> type if passed to a template that requires a type, or a partial=20
> template application if passed
> to a template that requires a template, but this isn't really=20
> satifying either.
Maybe the use of ... could be used to mean a placeholder for other=20
template parameters
using my_sorter =3D sorter<buffer<512, ...>>;
Vicente
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 07 Dec 2015 13:48:54 -0500
Raw View
On 2015-12-07 13:30, Vicente J. Botet Escriba wrote:
> Le 07/12/2015 13:28, Morwenn a =C3=A9crit :
>> Yeah, I realized too that it may not play nice with default template
>> parameters. I can't find a satisfying syntax for alias template
>> template either to hand-roll
>> partial applications without having to write subclasses either. There
>> is probably a small problem to be solved there, but the solutions do
>> not seem to be as
>> obvious as I thought they could be.
>>
>> Ideally, the nature of xxx<42> could be context-sensitive and be a
>> type if passed to a template that requires a type, or a partial
>> template application if passed
>> to a template that requires a template, but this isn't really
>> satifying either.
>=20
> Maybe the use of ... could be used to mean a placeholder for other
> template parameters
>=20
> using my_sorter =3D sorter<buffer<512, ...>>;
Given the trend to make 'auto' in a declaration be shorthand for
'template <typename T> ...T...', why not:
using my_sorter =3D sorter<buffer<512, auto>>;
....or even:
using my_sorter =3D sorter<buffer<512, auto...>>;
(The first would be sufficient for the example given, the second would
be a pack. I'd say something like "as many as are needed", but I think
the pack Just Works, and is more versatile.)
That said, it's not obvious from any of the above that my_sorter is a
template "type". Personally I think I'd rather use a long form of
template alias anyway, just as an aid to readability.
--=20
Matthew
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.