By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,530 Members | 891 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,530 IT Pros & Developers. It's quick & easy.

template #if preprocessor

P: n/a
how to make the following code work:

template<class TYPE>
void f2(char *buffer, TYPE *outer) {
// do something ...
// ...
#if (TYPE == int)
*outer = atoi(buffer);
#endif
#if (TYPE == double)
*outer = atof(buffer);
#endif
#if (TYPE == char)
strcpy(outer, buffer);
#endif
// release memory here
// ...
return;
}

it is not working but maybe you know how to modify it to make it
work...
K

Aug 8 '07 #1
Share this Question
Share on Google+
5 Replies


P: n/a
kRyszard wrote:
how to make the following code work:

template<class TYPE>
void f2(char *buffer, TYPE *outer) {
// do something ...
// ...
#if (TYPE == int)
*outer = atoi(buffer);
#endif
#if (TYPE == double)
*outer = atof(buffer);
#endif
#if (TYPE == char)
strcpy(outer, buffer);
#endif
// release memory here
// ...
return;
}

it is not working but maybe you know how to modify it to make it
work...
K
macro and preprocessor are done during preprocessing time,
template initiation is done compile-time, which is after
preprocessing-time, you can't mix them up
Aug 8 '07 #2

P: n/a
kRyszard wrote:
how to make the following code work:

template<class TYPE>
void f2(char *buffer, TYPE *outer) {
// do something ...
// ...
#if (TYPE == int)
*outer = atoi(buffer);
#endif
#if (TYPE == double)
*outer = atof(buffer);
#endif
#if (TYPE == char)
strcpy(outer, buffer);
#endif
// release memory here
// ...
return;
}

it is not working but maybe you know how to modify it to make it
work...
As Alf mentioned, boost::lexical_cast maybe work well with only the
integral types in your case; from the OP, when the type is char, the
function just wants to do a string copy.

So my suggestion is don't borrow template if it's only because it's fancy.

you can do the integral types with template using lexical_cast, and
write an additional overloaded function to handle type char
#include <boost/lexical_cast.hpp>
#include <iostream>

using namespace boost;
using namespace std;

template <typename T>
T f2(char const* buffer) {
return lexical_cast<T>(buffer);
}

void f2(char const* buffer, char* out) {
strcpy(out, buffer);
}

int main()
{
cout << f2<int>("1000") << endl;
cout << f2<double>("1.0") << endl;

char out[100];
f2("hello", out);
cout << out << endl;
}
Aug 8 '07 #3

P: n/a
joe
On Aug 8, 8:50 am, kRyszard <kry...@gmail.comwrote:
how to make the following code work:

template<class TYPE>
void f2(char *buffer, TYPE *outer) {
// do something ...
// ...
#if (TYPE == int)
*outer = atoi(buffer);
#endif
#if (TYPE == double)
*outer = atof(buffer);
#endif
#if (TYPE == char)
strcpy(outer, buffer);
#endif
// release memory here
// ...
return;

}
First thing, as was mentioned else where, the #if statements are
preprocessor statements and are applied well before the template
instantiation mechanism comes into play. Second, for what you are
doing, you can just use function overloads to implement your
conversions. That is,

void f2(char * buffer, char * out)
{

}

If you are going to mess with templates, I would suggest "C++
Templates" by Vandevoorde and Josuttis, however I can give you a
couple of pointers to get you started.

First, consider an existing solution such as boost::lexical_cast
(www.boost.org). The only problem with it is that it uses streams as
it's underpinnings and can therefore be slow compared to atoi() etc.
Most often though, this kind of conversion isn't done often enough to
warrant more effort than that.

If you feel that you are in the category where performance matters or
if you are just doing this as an exercise to learn templates, then I
can offer the following advice.

1) All of the # prefixed statements are C++ preprocessor statements
and don't work the way you are trying above.

2) The way you would set up your template specializations would look
like:

template <typename TYPE>
void f2(char * buffer, TYPE *outer)
{
// Do something generic like whine about this conversion not being
taken into account or possibly
// use #error
}

// Now specialize for the cases we know how to handle

template <>
void f2<int>(char * buffer, int * outer)
{
// convert to int
*outer = atoi(buffer);
}

template <>
void f2<double>(char * buffer, double * outer)
{
// convert to double
*outer = atof(buffer);
}

// the rest follow a similar pattern

Now, I didn't change the interface from what you posted, but
somewhere, you will want to verify that someone didn't just ask to
convert "Hello World" into a double or whatever, but since I don't
know your inputs I won't say much else about that.

Aug 8 '07 #4

P: n/a
joe
Ahhh, I've been Googled. Didn't mean to submit the last message.

Anyway, I was going to recommend just a series of function overloads
instead of the templates.

void f2(char * buffer, char * out)
{
// handle char *
}
void f2(char * buffer, int * out)
{
*out = atoi(buffer);
}

And so forth. No need for templates for this usage. However, I did
give in the previous, not quite edited in the way I would wish
message, a way to do it with templates. :) I'm quitting now before I
do some other weird edit and send thing.

joe

Aug 8 '07 #5

P: n/a
On Aug 8, 2:50 pm, kRyszard <kry...@gmail.comwrote:
how to make the following code work:
template<class TYPE>
void f2(char *buffer, TYPE *outer) {
// do something ...
// ...
#if (TYPE == int)
*outer = atoi(buffer);
#endif
#if (TYPE == double)
*outer = atof(buffer);
#endif
#if (TYPE == char)
strcpy(outer, buffer);
#endif
// release memory here
// ...
None of my business, of course, but what memory are you
releasing?
return;
}
it is not working but maybe you know how to modify it to make it
work...
In this precise case, of course, the obvious solution is:

template< typename T >
void
f2( char const* buffer, T* dest )
{
std::istrstream s( buffer, strlen( buffer ) ) ;
s >*dest ;
// Error checking here...
}

If this is just an example of a more general problem, of
course...

template< typename T >
struct Cvt
{
static T convert( char const* buffer ) ;
} ;

template< typename T >
void
f2( char const* buffer, T* dest )
{
// ...
*dest = Cvt< T >::convert( buffer ) ;
// ...
}

template<>
struct Cvt< int >
{
static int convert( char const* buffer )
{
return atoi( buffer ) ;
}
} ;

template<>
struct Cvt< double >
{
static int convert( char const* buffer )
{
return atof( buffer ) ;
}
} ;

// ...

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Aug 9 '07 #6

This discussion thread is closed

Replies have been disabled for this discussion.