Topic: Generics and member function types [N2855 and old std::MoveConstructible]
Author: "Niels Dekker - no reply address" <invalid@this.is.invalid>
Date: Sun, 14 Jun 2009 20:09:14 CST Raw View
> // C++0x:
> class vector
> {
> public:
> value_type & at(size_type) &;
> value_type && at(size_type) &&;
> value_type const& at(size_type) const&;
> };
Please note that the declarations of the at(size_type) member functions in
this example of mine differ from the ones of std::vector, from the C++0x
Working Draft, www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2857.pdf
The current C++0x std::vector::at(size_type) functions don't have
ref-qualifiers. As a consequence, when you call std::vector::at on an
rvalue, it returns an lvalue reference. (As it did in C++03.)
> // Hypothetical C++ inc. your "qualifiers" keyword:
> class vector
> {
> public:
> template <qualifiers CV>
> value_type CV at(size_type) CV;
> };
That would look very nice to me :-)
Kind regards, Niels
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: SG <s.gesemann@gmail.com>
Date: Sun, 14 Jun 2009 20:08:43 CST Raw View
On 14 Jun., 15:25, "Niels Dekker - no reply address"
<inva...@this.is.invalid> wrote:
> "SG" <s.gesemann> wrote:
> > It already bugs me that you can't write std::memfun in a
> > truly generic way
>
> I assume you mean std::mem_fun. (Mind the underscore!)
>
> > but you have to consider four cases for different
> > const/volatile versions of member functions.
>
> That's a pity, indeed.
>
> > IMHO, we ought to be able to handle things like
> > noexcept, const, volatile without writing different
> > versions for every special case. One approach would
> > be to
>
> > o) extend the template system with a new kind of
> > parameter for cv qualifiers
>
> Don't forget the ref-qualifiers!
Right. They probably make things even more complicated. A tool like
std::mem_fun (or the future std::bind) should support all combinations
of noexpect, const, volatile and lref for member functions. But the
number of those combinations is 16 --- sixteen!
> > o) make noexcept parameterisable
In the example below I used noexcept with a boolean parameter. Its
default value could be true so that
void foo(); // is equivalent to
noexcept<false> void foo();
noexcept void bar(); // is equivalent to
noexcept<true> void bar();
> > --------8<--------[ BEGIN hypothetical C++ ]--------8<--------
>
> > template< bool NoExcept, typename Ret, class Clz,
> > qualifiers CV, typename ... Parms >
> > class memfun_t
> > {
> > public:
> > typedef noexcept<NoExcept> Ret (Clz::*pmf_t)(Parms...) CV;
> > typedef Clz CV* objptr_t;
In case "CV" includes a ref qualifier this won't work.
>
> > memfun_t(pmf_t pmf) : pmf(pmf) {}
>
> > noexcept<NoExcept>
> > Ret operator()(objptr_t po, P... params) const
> > {
> > return (*po)(std::forward<P>(params)...);
Of course, this should have been
return (po->*pmf)(std::forward<P>(params)...);
> > }
> > private:
> > pmf_t pmf;
> > };
>
> > template< bool NoExcept, typename Ret, class Clz,
> > qualifiers CV, typename ... Parms >
> > memfun_t<NoExcept,Ret,Clz,CV,Params...>
> > memfun( noexcept<NoExcept> Ret (Clz::*pmf)(Params...) CV )
> > {
> > return memfun_t<NoExcept,Ret,Clz,CV,Params...>(pmf);
> > }
>
> > --------8<--------[ END hypothetical C++ ]--------8<--------
>
> I think such a language extension would be very useful. Especially if it
> could also help in a different context, having to write overloads for const,
> non-const lvalue, and non-const rvalue:
>
> // C++0x:
> class vector
> {
> public:
> value_type & at(size_type) &;
> value_type && at(size_type) &&;
> value_type const& at(size_type) const&;
> };
>
> // Hypothetical C++ inc. your "qualifiers" keyword:
> class vector
> {
> public:
> template <qualifiers CV>
> value_type CV at(size_type) CV;
> };
Interesting. What would be the most sensible rule for template
parameter deduction in situations like these? For that matter: Should
you be able to explicitly specify such a parameter? Example:
std::vector<double> vec (1, 3.14159265);
cout << vec.at<const>(0);
In this case you probably should have declared the member template as
template <qualifiers CV>
value_type CV&& at(size_type) CV;
to prevent return-by-value. If this template parameter (for a set of
qualifiers) can be specified explicitly we would also need a syntax to
express an empty qualifier set.
still pondering,
SG
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Niels Dekker - no reply address" <invalid@this.is.invalid>
Date: Sun, 14 Jun 2009 07:25:14 CST Raw View
"SG" <s.gesemann> wrote:
> It already bugs me that you can't write std::memfun in a
> truly generic way
I assume you mean std::mem_fun. (Mind the underscore!)
> but you have to consider four cases for different
> const/volatile versions of member functions.
That's a pity, indeed.
> IMHO, we ought to be able to handle things like
> noexcept, const, volatile without writing different
> versions for every special case. One approach would
> be to
>
> o) extend the template system with a new kind of
> parameter for cv qualifiers
Don't forget the ref-qualifiers!
> o) make noexcept parameterisable
>
> --------8<--------[ BEGIN hypothetical C++ ]--------8<--------
>
> template< bool NoExcept, typename Ret, class Clz,
> qualifiers CV, typename ... Parms >
> class memfun_t
> {
> public:
> typedef noexcept<NoExcept> Ret (Clz::*pmf_t)(Parms...) CV;
> typedef Clz CV* objptr_t;
>
> memfun_t(pmf_t pmf) : pmf(pmf) {}
>
> noexcept<NoExcept>
> Ret operator()(objptr_t po, P... params) const
> {
> return (*po)(std::forward<P>(params)...);
> }
> private:
> pmf_t pmf;
> };
>
> template< bool NoExcept, typename Ret, class Clz,
> qualifiers CV, typename ... Parms >
> memfun_t<NoExcept,Ret,Clz,CV,Params...>
> memfun( noexcept<NoExcept> Ret (Clz::*pmf)(Params...) CV )
> {
> return memfun_t<NoExcept,Ret,Clz,CV,Params...>(pmf);
> }
>
> --------8<--------[ END hypothetical C++ ]--------8<--------
I think such a language extension would be very useful. Especially if it
could also help in a different context, having to write overloads for const,
non-const lvalue, and non-const rvalue:
// C++0x:
class vector
{
public:
value_type & at(size_type) &;
value_type && at(size_type) &&;
value_type const& at(size_type) const&;
};
// Hypothetical C++ inc. your "qualifiers" keyword:
class vector
{
public:
template <qualifiers CV>
value_type CV at(size_type) CV;
};
Kind regards, Niels
--
Niels Dekker
http://www.xs4all.nl/~nd/dekkerware
Scientific programmer at LKEB, Leiden University Medical Center
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]