Runtime type checking in a simple template function

U

utab

Dear all,

I have a simple template to convert its argument to a string:

template<typename T>
string AtoStr(T t){
ostringstream sstrm;
sstrm << t;
return sstrm.str();
}

This is simple with stringstream. But lets say if the argument is a
double 1.0 or an int 1

The returned value is the same "1" without decimal point. I guess the
library is optimizing the output on this one. But I need to do sth to
cope with this:

+ if the type of the argument is an int, then it should convert it to
"1"
+ if the type of the argument is a double like 1.0 then it should
convert it to "1.0".

I am not so sure if output manipulators can help me.

Best regards,
 
V

Victor Bazarov

utab said:
Dear all,

I have a simple template to convert its argument to a string:

template<typename T>
string AtoStr(T t){
ostringstream sstrm;
sstrm << t;
return sstrm.str();
}

This is simple with stringstream. But lets say if the argument is a
double 1.0 or an int 1

The returned value is the same "1" without decimal point. I guess the
library is optimizing the output on this one. But I need to do sth to
cope with this:

+ if the type of the argument is an int, then it should convert it to
"1"
+ if the type of the argument is a double like 1.0 then it should
convert it to "1.0".

I am not so sure if output manipulators can help me.

Why bother. Specialise or overload.

V
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

Dear all,

I have a simple template to convert its argument to a string:

template<typename T>
string AtoStr(T t){
ostringstream sstrm;
sstrm << t;
return sstrm.str();
}

This is simple with stringstream. But lets say if the argument is a
double 1.0 or an int 1

The returned value is the same "1" without decimal point. I guess the
library is optimizing the output on this one. But I need to do sth to
cope with this:

+ if the type of the argument is an int, then it should convert it to
"1"
+ if the type of the argument is a double like 1.0 then it should
convert it to "1.0".

I am not so sure if output manipulators can help me.

Yes, since the bahaviour when the argument is an int is what you want
all you need to do is to fix the behaviour when the value is a double.
This you can do by proividing special double-version of the method:

#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>

template<typename T>
std::string AtoStr(T t){
std::eek:stringstream sstrm;
sstrm << t;
return sstrm.str();
}

std::string AtoStr(double t){
std::eek:stringstream sstrm;
int i = t;
if (i == t)
sstrm << std::fixed << std::setprecision(1) << t;
else
sstrm << t;
return sstrm.str();
}


int main()
{
std::cout << AtoStr(1.0) << "\n";
std::cout << AtoStr(1.13456) << "\n";
std::cout << AtoStr("sdtfg") << "\n";
}

The if (i == t) business is just to check if the number is an integer
(not the type) in which case we don't need to print more than one 0
after the dot. You might want to work a bit at how you want other
doubles represented (number of digits and so on).

Notice that this does not work for floats. You can use this for floats:

std::string AtoStr(float t)
{
return AtoStr(double(t));
}
 
U

utab

Why bother. Specialise or overload.

Hmm, I will read on template specialization. Is that right

Thanks
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

Dear all,

I have a simple template to convert its argument to a string:

By the way, regarding the subject of your post: templates are compile-
time so runtime typechecking won't do you any good since all the
decisions are already made when the app runs.
 
U

utab

Yes, since the bahaviour when the argument is an int is what you want
all you need to do is to fix the behaviour when the value is a double.
This you can do by proividing special double-version of the method:

#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>

template<typename T>
std::string AtoStr(T t){
std::eek:stringstream sstrm;
sstrm << t;
return sstrm.str();

}

std::string AtoStr(double t){
std::eek:stringstream sstrm;
int i = t;
if (i == t)
sstrm << std::fixed << std::setprecision(1) << t;
else
sstrm << t;
return sstrm.str();

}

int main()
{
std::cout << AtoStr(1.0) << "\n";
std::cout << AtoStr(1.13456) << "\n";
std::cout << AtoStr("sdtfg") << "\n";

}

The if (i == t) business is just to check if the number is an integer
(not the type) in which case we don't need to print more than one 0
after the dot. You might want to work a bit at how you want other
doubles represented (number of digits and so on).

Notice that this does not work for floats. You can use this for floats:

std::string AtoStr(float t)
{
return AtoStr(double(t));

}

Thanks
 
J

Jim Langston

Erik Wikström said:
Yes, since the bahaviour when the argument is an int is what you want all
you need to do is to fix the behaviour when the value is a double. This
you can do by proividing special double-version of the method:

#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>

template<typename T>
std::string AtoStr(T t){
std::eek:stringstream sstrm;
sstrm << t;
return sstrm.str();
}

std::string AtoStr(double t){
std::eek:stringstream sstrm;
int i = t;
if (i == t)

Wouldn't this be better as:

if ( typeid( i ) == typeid( double ) )
 
S

Sarath

Yes, since the bahaviour when the argument is an int is what you want
all you need to do is to fix the behaviour when the value is a double.
This you can do by proividing special double-version of the method:

#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>

template<typename T>
std::string AtoStr(T t){
std::eek:stringstream sstrm;
sstrm << t;
return sstrm.str();

}

std::string AtoStr(double t){
std::eek:stringstream sstrm;
int i = t;
if (i == t)
sstrm << std::fixed << std::setprecision(1) << t;
else
sstrm << t;
return sstrm.str();

}

int main()
{
std::cout << AtoStr(1.0) << "\n";
std::cout << AtoStr(1.13456) << "\n";
std::cout << AtoStr("sdtfg") << "\n";

}

The if (i == t) business is just to check if the number is an integer
(not the type) in which case we don't need to print more than one 0
after the dot. You might want to work a bit at how you want other
doubles represented (number of digits and so on).

Notice that this does not work for floats. You can use this for floats:

std::string AtoStr(float t)
{
return AtoStr(double(t));

}

Seems this is the right method.
You can make use of iomanip function to control the input and output.

Regards,
Sarath

http://sarathc.wordpress.com/
 
S

Sarath

Yes, since the bahaviour when the argument is an int is what you want
all you need to do is to fix the behaviour when the value is a double.
This you can do by proividing special double-version of the method:

#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>

template<typename T>
std::string AtoStr(T t){
std::eek:stringstream sstrm;
sstrm << t;
return sstrm.str();

}

std::string AtoStr(double t){
std::eek:stringstream sstrm;
int i = t;
if (i == t)
sstrm << std::fixed << std::setprecision(1) << t;
else
sstrm << t;
return sstrm.str();

}

int main()
{
std::cout << AtoStr(1.0) << "\n";
std::cout << AtoStr(1.13456) << "\n";
std::cout << AtoStr("sdtfg") << "\n";

}

The if (i == t) business is just to check if the number is an integer
(not the type) in which case we don't need to print more than one 0
after the dot. You might want to work a bit at how you want other
doubles represented (number of digits and so on).

Notice that this does not work for floats. You can use this for floats:

std::string AtoStr(float t)
{
return AtoStr(double(t));

}

IMO, What Erik Said is the best solution.
You can make use of iomanip function to control the input and output.

Regards,
Sarath

http://sarathc.wordpress.com/
 
?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

Wouldn't this be better as:

if ( typeid( i ) == typeid( double ) )

No, the above will always be false since i is an int. The purpose if
the above is to check if the value of t is an integer (not of type
integer) in which case we only want to add a decimal sign and one
zero. If it isn't we will use more precision.
 
J

Jim Langston

Wouldn't this be better as:

if ( typeid( i ) == typeid( double ) )

- No, the above will always be false since i is an int. The purpose if
- the above is to check if the value of t is an integer (not of type
- integer) in which case we only want to add a decimal sign and one
- zero. If it isn't we will use more precision.

Yes, sorry, it should of been:

if ( typeid( t ) == typeid( int ))
 
?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

- No, the above will always be false since i is an int. The purpose if
- the above is to check if the value of t is an integer (not of type
- integer) in which case we only want to add a decimal sign and one
- zero. If it isn't we will use more precision.

Yes, sorry, it should of been:

if ( typeid( t ) == typeid( int ))

It will still be false because t is a double since that's how it's
declared.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,144
Latest member
KetoBaseReviews
Top