From: Nikolay Ivchenkov on 2 Jul 2010 09:04 Sometimes we need to duplicate code for cv-unqualified and cv- qualified types. For example, there is no way to specialize the following template template <class T> struct X; for any pointer type at once. We have to write 4 partial specializations as shown below: template <class T> struct X<T *> { /* ... */ }; template <class T> struct X<T *const> { /* ... */ }; template <class T> struct X<T *volatile> { /* ... */ }; template <class T> struct X<T *const volatile> { /* ... */ }; With additional kind of template parameters a single common partial specialization for pointer types might look like this: template <class T, const volatile cvq> struct X<T *cvq> { //... }; where cvq designates empty cv-qualification, const, volatile, or const volatile. Similarly, a single common partial specialization (instead of 16 partial specializations) for pointer to member function types might look like this: template < class R, class C, class... Params, const volatile ptr_cvq, const volatile fun_cvq > struct X<R (C::*ptr_cvq)(Params...) fun_cvq> { //... }; We might also implement non-const and const member functions in a single template: template <class T> class Vector { template <const cq = void> using iterator_type = T cq *; // here 'void' designates empty cv-qualification typedef iterator_type<> iterator; typedef iterator_type<const> const_iterator; template <const cq> iterator_type<cq> begin() cq; const_iterator cbegin() const { return begin<const>(); } template <const cq> T cq &front() cq; // ... }; // ... void f(Vector<int> const &c) { int i = c.begin(); // cq is deduced to const c.begin<const volatile>(); // ill-formed: template argument for cq // shall not contain volatile qualifier } Did the committee consider this language improvement? -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Dragan Milenkovic on 4 Jul 2010 05:52 Nikolay Ivchenkov wrote: > Sometimes we need to duplicate code for cv-unqualified and cv- > qualified types. For example, there is no way to specialize the > following template > template <class T> > struct X; > for any pointer type at once. We have to write 4 partial > specializations as shown below: > template <class T> > struct X<T *> { /* ... */ }; > template <class T> > struct X<T *const> { /* ... */ }; > template <class T> > struct X<T *volatile> { /* ... */ }; > template <class T> > struct X<T *const volatile> { /* ... */ }; Maybe you have already considered, but you can do it like this: template <class T> struct X<T * const> : public Y<T *, CQ_CONST> {}; or template <class T> struct X<T * const> : public Y<T *, true, false> {}; Of course, you put your implementation in Y which would be common for all qualifications. -- Dragan [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: terminator on 9 Jul 2010 23:12 On Jul 5, 12:52 am, Dragan Milenkovic <dra...(a)plusplus.rs> wrote: > Nikolay Ivchenkov wrote: > > Sometimes we need to duplicate code for cv-unqualified and cv- > > qualified types. For example, there is no way to specialize the > > following template > > template <class T> > > struct X; > > for any pointer type at once. We have to write 4 partial > > specializations as shown below: > > template <class T> > > struct X<T *> { /* ... */ }; > > template <class T> > > struct X<T *const> { /* ... */ }; > > template <class T> > > struct X<T *volatile> { /* ... */ }; > > template <class T> > > struct X<T *const volatile> { /* ... */ }; > > Maybe you have already considered, but you can do it like this: > > template <class T> > struct X<T * const> : public Y<T *, CQ_CONST> {}; > > or > > template <class T> > struct X<T * const> : public Y<T *, true, false> {}; > > Of course, you put your implementation in Y which would be common > for all qualifications. > and that would again require multiple(4,16,...) definition lines for x. regards, FM. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Johannes Schaub (litb) on 10 Jul 2010 04:07 Dragan Milenkovic wrote: > Nikolay Ivchenkov wrote: >> Sometimes we need to duplicate code for cv-unqualified and cv- >> qualified types. For example, there is no way to specialize the >> following template >> template <class T> >> struct X; >> for any pointer type at once. We have to write 4 partial >> specializations as shown below: >> template <class T> >> struct X<T *> { /* ... */ }; >> template <class T> >> struct X<T *const> { /* ... */ }; >> template <class T> >> struct X<T *volatile> { /* ... */ }; >> template <class T> >> struct X<T *const volatile> { /* ... */ }; > > Maybe you have already considered, but you can do it like this: > > template <class T> > struct X<T * const> : public Y<T *, CQ_CONST> {}; > > or > > template <class T> > struct X<T * const> : public Y<T *, true, false> {}; > > Of course, you put your implementation in Y which would be common > for all qualifications. > I think implementing that template in particular was just an example for making his point. In fact for implementing this one, there is an easy solution for specializing all pointer types at once: template<typename T> struct Ximpl; template<typename T> struct Ximpl<T *const volatile> { /* ... */ }; template<typename T> struct X : Ximpl<T const volatile> { }; Of course this way you lost the original type, but you can easily pass it along unmodified to "Ximpl". -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Dragan Milenkovic on 11 Jul 2010 04:40 On 07/10/2010 04:12 PM, terminator wrote: > On Jul 5, 12:52 am, Dragan Milenkovic<dra...(a)plusplus.rs> wrote: >> Nikolay Ivchenkov wrote: >>> Sometimes we need to duplicate code for cv-unqualified and cv- >>> qualified types. For example, there is no way to specialize the >>> following template >>> template<class T> >>> struct X; >>> for any pointer type at once. We have to write 4 partial >>> specializations as shown below: >>> template<class T> >>> struct X<T *> { /* ... */ }; >>> template<class T> >>> struct X<T *const> { /* ... */ }; >>> template<class T> >>> struct X<T *volatile> { /* ... */ }; >>> template<class T> >>> struct X<T *const volatile> { /* ... */ }; >> >> Maybe you have already considered, but you can do it like this: >> >> template<class T> >> struct X<T * const> : public Y<T *, CQ_CONST> {}; >> >> or >> >> template<class T> >> struct X<T * const> : public Y<T *, true, false> {}; >> >> Of course, you put your implementation in Y which would be common >> for all qualifications. >> > > and that would again require multiple(4,16,...) definition lines for > x. It is still better to have one-liners with no body than 4 copy/pasted implementations, don't you agree? -- Dragan [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Pages: 1 Prev: Available C++ Libraries FAQ Next: Job for Boost filtered iterators ??? |