473,406 Members | 2,698 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

how to cause const promotion for template code

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?
Jul 22 '05 #1
7 1824
Siemel Naran wrote in
news:_%*******************@bgtnsc05-news.ops.worldnet.att.net 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/
Jul 22 '05 #2
"Rob Williscroft" <rt*@freenet.co.uk> 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.
Jul 22 '05 #3
Siemel Naran wrote in
news:wm*******************@bgtnsc05-news.ops.worldnet.att.net 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/
Jul 22 '05 #4
Siemel Naran wrote:
"Rob Williscroft" <rt*@freenet.co.uk> 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.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

Jul 22 '05 #5
Siemel Naran wrote:
"Rob Williscroft" <rt*@freenet.co.uk> 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.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

Jul 22 '05 #6
"Dietmar Kuehl" <di***********@yahoo.com> 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);
Jul 22 '05 #7
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.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

Jul 22 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Chris Johnson | last post by:
Greetings all: I come across an interesting question (to me anyway) and I do not know the answer. Code/Questions follow: #include <iostream> #if 0 // uncommenting *should* make call...
0
by: Prune Tracy | last post by:
Hello. As practice in programming using templates, and for interest's sake, I wrote some code to see how floating point numbers are stored on my system. I hoped to be able to use it like: ...
3
by: Michael T Decerbo | last post by:
The code below compiles without warnings or errors under g++ 3.2.1 on Solaris, gcc 3.2.2 on Linux, and MSVC 6.0 on Windows. Under g++ (GCC) 3.3.2, it produces the following errors: % g++ -Wall...
2
by: Steve | last post by:
Hi all, Is template code "always" inlined??? Or will compilers instantiate template functions separately if they are large? Also, what happens to the code if explicit instantiation mechanism...
0
by: gao_bolin | last post by:
I have a library that has a class Signal<T> whose data type is templated. The class comes with a whole bunch of functions and objects to do various processing on the signal. What I would like to...
10
by: dee | last post by:
Hi How can I cause a postback in code, e.g., without clicking on a button? Thanks. Dee
0
by: Jack | last post by:
Hi, I want to override an overridable method in some base class from my class. It works fine if I manually code the method (as one would expect), but I want the IDE to auto-generate the template...
0
by: Thelma Roslyn Lubkin | last post by:
dizzy <dizzy@roedu.netwrote: : Hello : When working with template heavy code one will have to face the : inherent "problems" of the inclusion model because of the requirement : to provide the...
4
by: Pallav singh | last post by:
Hi All, i am getting error during explicit function Instantiation for a class Template if i do explicit Instantiation of class it work and all function symbol i get in object file But if i...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.