Topic: Add a new template parameter kind--Qualifiers


Author: tslettebo@chello.no.nospam (=?iso-8859-1?Q?Terje_Sletteb=F8?=)
Date: Sun, 15 Jun 2003 05:25:49 +0000 (UTC)
Raw View
>Re: const functions and metacode

"Daryle Walker" <dwalker07@snet.net> wrote in message
news:dwalker07-369688.03083214062003@newssvr10-ext.news.prodigy.com...
>
> I think Dhruv's point was something like:
>
> struct test1
> {
>    int *a;
>
>    test1() : a(new int[5]) {}
>    ~test1() { delete [] a; }
>
>    int &  at(int i) { return a[i]; }
>
>    int const &  at(int i) const { return a[i]; }
> };
>
> The two "at" methods are token-for-token identical except for the
> qualifier differences.  Doesn't this seem familiar?  We took care of
> this problem for similarly used types and similarly used constants
with
> templates!  Why not do the same for qualifiers:
>
> struct test2
> {
>    int *a;
>
>    test2() : a(new int[5]) {}
>    ~test2() { delete [] a; }
>
>    template < qualifier Q >
>    int Q &  at(int i) Q { return a[i]; }
> };
>
> We have to add a new keyword "qualifier".

Interesting suggestion.

This may also be used to solve the "forwarding problem" [1]. To quote
from option #7 (Rvalue reference + modified argument deduction) (perfect
forwarding):

template<class A1> void f(A1 && a1)
{
    return g(static_cast<A1 &&>(a1));
}

This option requires rvalue references ("&&") [2], and uses the
"modified argument deduction" of option #5 (Non-const reference +
modified argument deduction):

--- Start quote ---

With a relatively small change to 14.8.2.1, it is possible to make A1 in
the following snippet:

template<class A1> void f(A1 & a1)
{
}

int main()
{
    f(5);
}

to be deduced as int const, and not plain int. As a side effect,
solution #1 now will (const-correctly) work for all argument types.

The upside of this approach are that it requires a small, isolated
language change, that is relatively independent of the rest of the
language, including the move proposal [4].

One downside is that the change breaks existing code:

template<class A1> void f(A1 & a1)
{
    std::cout << 1 << std::endl;
}

void f(long const &)
{
    std::cout << 2 << std::endl;
}

int main()
{
    f(5);              // prints 2 under the current rules, 1 after the
change
    int const n(5);
    f(n);              // 1 in both cases
}

--- End quote ---

Using your template qualifier parameter, it would be possible to do
this, _without_ breaking existing code. Option #7 could then be written
as:

template<class A1, qualifier Q1> void f(A1 Q1 && a1)
{
    return g(static_cast<A1 Q1 &&>(a1));
}

Combined with [3], one could avoid having to write one overload for each
number of arguments, and have unlimited number of arguments. The version
without qualifier parameter is:

template<class ... Arguments> void f(Arguments && a)
{
    return g(static_cast<Arguments &&>(a));
}

Combining this with a qualifier parameter may be tricky, but might work.
Perhaps like this:

template<class ... Arguments, qualifier ... Qualifiers> void f(Arguments
Qualifiers && a)
{
    return g(static_cast<Arguments Qualifiers &&>(a));
}

There are several different ways of handling the forwarding problem
(enumerated in [1]), some not handling all cases, and some requiring a
fixed maximum number of parameters, and N or 2N amount of code, but the
above solution gives perfect forwarding (case #7 in [1]), with a single
line of code.

This requires:

- rvalue references [2]
- variable-length function and template argument lists [3]
- Your template qualifier parameter suggestion


Regards,

Terje


References:

[1] "The Forwarding Problem: Arguments"
(http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm)
[2] "A Proposal to Add Move Semantics Support to the C++ Language"
(http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1377.htm) (this
both gives move semantics, and perfect forwarding)
[3] "Typesafe Variable-length Function and Template Argument Lists"
(http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1483.pdf)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: tslettebo@chello.no.nospam (=?iso-8859-1?Q?Terje_Sletteb=F8?=)
Date: Sun, 15 Jun 2003 22:13:53 +0000 (UTC)
Raw View
"Terje Sletteb=F8" <tslettebo@chello.no.nospam> wrote in message
news:QRCGa.11682$KF1.273613@amstwist00...
>
> There are several different ways of handling the forwarding problem
> (enumerated in [1]), some not handling all cases, and some requiring a
> fixed maximum number of parameters, and N or 2N amount of code, but
the
> above solution gives perfect forwarding (case #7 in [1]), with a
single
> line of code.
>
> This requires:
>
> - rvalue references [2]
> - variable-length function and template argument lists [3]
> - Your template qualifier parameter suggestion

Having read up, again, on the variable-length argument list proposal, it
appears that it is sufficient, in itself, to provide perfect forwarding,
so in this case, the template qualifier parameter suggestion isn't
needed, after all.


Regards,

Terje

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]