Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > how to cause const promotion for template code

Reply
Thread Tools

how to cause const promotion for template code

 
 
Siemel Naran
Guest
Posts: n/a
 
      11-30-2004
Hi. I have a function

template <class InputIter, class OutputIter>
void f(InputIter begin, InputIter end, OutputIter result);

With c of type char* and cc of type const char*, the code f(c,c,cc) calls
f<char*, const char *>, which is fine.

But f(c,c,c) calls a new instantiation f<char*,char*> whereas I'd like it to
call f<const char*,char*>.

How to make this happen?


 
Reply With Quote
 
 
 
 
Rob Williscroft
Guest
Posts: n/a
 
      11-30-2004
Siemel Naran wrote in
news:_%Xqd.74482$(E-Mail Removed) in
comp.lang.c++:

> Hi. I have a function
>
> template <class InputIter, class OutputIter>
> void f(InputIter begin, InputIter end, OutputIter result);
>
> With c of type char* and cc of type const char*, the code f(c,c,cc)
> calls f<char*, const char *>, which is fine.


Well a "char const *" *isn't* an output iterator, which isn't my
defenition of "fine".

>
> But f(c,c,c) calls a new instantiation f<char*,char*> whereas I'd like
> it to call f<const char*,char*>.


Why, what difference does it make ?. If you're trying to avoid code bloat
some modern compilers come with optimizers that can do this for you.

>
> How to make this happen?
>


template < typename T >
inline void f( T *a, T *b, T *c )
{
f< T const *, T * >( a, b, c );
}

Rob.
--
http://www.victim-prime.dsl.pipex.com/
 
Reply With Quote
 
 
 
 
Siemel Naran
Guest
Posts: n/a
 
      11-30-2004
"Rob Williscroft" <(E-Mail Removed)> wrote in message
> Siemel Naran wrote in


> > template <class InputIter, class OutputIter>
> > void f(InputIter begin, InputIter end, OutputIter result);
> >
> > With c of type char* and cc of type const char*, the code f(c,c,cc)
> > calls f<char*, const char *>, which is fine.

>
> Well a "char const *" *isn't* an output iterator, which isn't my
> defenition of "fine".


Oops. That should have been f(cc,cc,c) which calls f<const char*, char*>
which is fine.

> Why, what difference does it make ?. If you're trying to avoid code bloat
> some modern compilers come with optimizers that can do this for you.


But some don't, so I have to do it.


> template < typename T >
> inline void f( T *a, T *b, T *c )
> {
> f< T const *, T * >( a, b, c );
> }


First, can one specialize member functions? My function f is actually a
member function.

Second, how to handle STL iterators. For example, I want
f<std::deque<int>::iterator, std::deque<int>::iterator> to call
f<std::deque<int>::const_iterator, std::deque<int>::iterator>. Do you know
how to achieve this?

Thanks.


 
Reply With Quote
 
Rob Williscroft
Guest
Posts: n/a
 
      11-30-2004
Siemel Naran wrote in
news:wm3rd.75692$(E-Mail Removed) in
comp.lang.c++:

>> Why, what difference does it make ?. If you're trying to avoid code
>> bloat some modern compilers come with optimizers that can do this for
>> you.

>
> But some don't, so I have to do it.


Do you know this for a fact, have you measured a performance drop
because of it ?

>
>
>> template < typename T >
>> inline void f( T *a, T *b, T *c )
>> {
>> f< T const *, T * >( a, b, c );
>> }

>
> First, can one specialize member functions? My function f is actually
> a member function.


The above isn't a specialization its an overload, and yes you can
overload member functions even when they are templates.

Also you can only explicitly specialze functions. eg:

template < typename T > void f( T ) {}
template <> void f< int >( int ) {}

>
> Second, how to handle STL iterators. For example, I want
> f<std::deque<int>::iterator, std::deque<int>::iterator> to call
> f<std::deque<int>::const_iterator, std::deque<int>::iterator>. Do you
> know how to achieve this?
>


It can't be done as there is now way of getting a const_iterator
given *only* an iterator (except when the iterator is a pointer).

Rob.
--
http://www.victim-prime.dsl.pipex.com/
 
Reply With Quote
 
Dietmar Kuehl
Guest
Posts: n/a
 
      11-30-2004
Siemel Naran wrote:
> "Rob Williscroft" <(E-Mail Removed)> wrote in message
> > template < typename T >
> > inline void f( T *a, T *b, T *c )
> > {
> > f< T const *, T * >( a, b, c );
> > }

>
> First, can one specialize member functions? My function f is

actually a
> member function.


How is this question related to the above function? This is not a
specialization but an overload and you surely can overload member
functions. Other than this, the answer to your question is: no.
Actually, you can only fully specialize global functions while you
would require a partial specialization anyway.

> Second, how to handle STL iterators. For example, I want
> f<std::deque<int>::iterator, std::deque<int>::iterator> to call
> f<std::deque<int>::const_iterator, std::deque<int>::iterator>.


Since there is no requirement that an iterator has a constant
counterpart, there is no requirement for something like
'const_iterator' in iterator traits. You might get away by
using your own traits class:

template <typename It> struct const_it { typedef It type; };
template <typename T> struct const_it<T*> { typedef T const* type; };
template <typename T, typename A>
struct const_it<std::deque<T, A>::iterator> {
typedef std::deque<T, A>::const_iterator type;
};
// ...

.... and use this in your function's implementation:

template <typename InputIter, typename OutputIter>
OutputIter f(InputIter beg, InputIter end, OutputIter to) {
return f<typename const_it<InputIter>::type, OutputIter>(beg, end,
to);
}

A complication is that 'std::vector<T>'s iterator may actually be
'T*' in which case you would attempt to specialize twice for the
type 'T*' if you added vector's iterator to the above specialization.
--
<(E-Mail Removed)> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

 
Reply With Quote
 
Dietmar Kuehl
Guest
Posts: n/a
 
      11-30-2004
Siemel Naran wrote:
> "Rob Williscroft" <(E-Mail Removed)> wrote in message
> > template < typename T >
> > inline void f( T *a, T *b, T *c )
> > {
> > f< T const *, T * >( a, b, c );
> > }

>
> First, can one specialize member functions? My function f is

actually a
> member function.


How is this question related to the above function? This is not a
specialization but an overload and you surely can overload member
functions. Other than this, the answer to your question is: no.
Actually, you can only fully specialize global functions while you
would require a partial specialization anyway.

> Second, how to handle STL iterators. For example, I want
> f<std::deque<int>::iterator, std::deque<int>::iterator> to call
> f<std::deque<int>::const_iterator, std::deque<int>::iterator>.


Since there is no requirement that an iterator has a constant
counterpart, there is no requirement for something like
'const_iterator' in iterator traits. You might get away by
using your own traits class:

template <typename It> struct const_it { typedef It type; };
template <typename T> struct const_it<T*> { typedef T const* type; };
template <typename T, typename A>
struct const_it<std::deque<T, A>::iterator> {
typedef std::deque<T, A>::const_iterator type;
};
// ...

.... and use this in your function's implementation:

template <typename InputIter, typename OutputIter>
OutputIter f(InputIter beg, InputIter end, OutputIter to) {
return f<typename const_it<InputIter>::type, OutputIter>(beg, end,
to);
}

A complication is that 'std::vector<T>'s iterator may actually be
'T*' in which case you would attempt to specialize twice for the
type 'T*' if you added vector's iterator to the above specialization.
--
<(E-Mail Removed)> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

 
Reply With Quote
 
Siemel Naran
Guest
Posts: n/a
 
      12-02-2004
"Dietmar Kuehl" <(E-Mail Removed)> wrote in message
> Siemel Naran wrote:


> > First, can one specialize member functions? My function f is


> How is this question related to the above function? This is not a
> specialization but an overload and you surely can overload member
> functions. Other than this, the answer to your question is: no.


Why can one not specialize member functions?


> Since there is no requirement that an iterator has a constant
> counterpart, there is no requirement for something like
> 'const_iterator' in iterator traits. You might get away by
> using your own traits class:
>
> template <typename It> struct const_it { typedef It type; };
> template <typename T> struct const_it<T*> { typedef T const* type; };
> template <typename T, typename A>
> struct const_it<std::deque<T, A>::iterator> {
> typedef std::deque<T, A>::const_iterator type;
> };
> // ...
>
> ... and use this in your function's implementation:
>
> template <typename InputIter, typename OutputIter>
> OutputIter f(InputIter beg, InputIter end, OutputIter to) {
> return f<typename const_it<InputIter>::type, OutputIter>(beg, end,
> to);
> }
>
> A complication is that 'std::vector<T>'s iterator may actually be
> 'T*' in which case you would attempt to specialize twice for the
> type 'T*' if you added vector's iterator to the above specialization.


Yes, this is a good idea. BTW, is the following legal in a fully ANSI
compliant compiler

template <typename Container>
struct const_it<typename Container::iterator> {
typedef typename Container::const_iterator type;
};

I guess not, because the compiler might have a hard time deducing
'Container' given a specialization const_it<MyIter>.


But it gets me thinking to a new solution.

template <class Container, class InputIter, class OutputIter>
void f(const Container&, typename Container::const_iterator begin, typename
Container::const_iterator end, OutputIter result);

We explicitly pass in the container in order that we can use
Container::const_iterator. There will be a specialization

template <class T, class OutputIter>
void f<const T*,const T*, OutputIter>(const T*, const T* begin, const T*
end, OutputIter result);


 
Reply With Quote
 
Dietmar Kuehl
Guest
Posts: n/a
 
      12-02-2004
Siemel Naran wrote:
> Why can one not specialize member functions?


Because it is sufficient to overload them.

> BTW, is the following legal in a fully ANSI compliant compiler
>
> template <typename Container>
> struct const_it<typename Container::iterator> {
> typedef typename Container::const_iterator type;
> };


No: the container cannot be deduced if two containers share a common
iterator type. Still, the typedefs of related types may differ
for the two containers. The same is true for argument type deduction
in function templates: you cannot use a nested type.

> But it gets me thinking to a new solution.
>
> template <class Container, class InputIter, class OutputIter>
> void f(const Container&, typename Container::const_iterator begin,

typename
> Container::const_iterator end, OutputIter result);


In this case, I'd go with a "range" which would be a pair of member
function ('begin()' and 'end()'; optionally also 'rbegin()' and
'rend()' for reversible ranges) plus a set of supporting typedefs.
The function would than just get one parameter for the input sequence,
namely the range.
--
<(E-Mail Removed)> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
const vector<A> vs vector<const A> vs const vector<const A> Javier C++ 2 09-04-2007 08:46 PM
Casting int'** to 'const int * const * const' dosn't work, why? Jonas.Holmsten@gmail.com C Programming 11 07-01-2007 06:16 PM
Data Recovery Book and Online Business Promotion, Products Sales Promotion, Search Engine Optimization and Online Data Recovery Training services Author Tarun Tyagi Cisco 0 12-15-2004 01:52 AM
The promotion code "MSUU4C8E3475" is not a valid promotion code Sam-Hong Kong MCDST 2 03-04-2004 06:47 PM



Advertisments