simple(?) question about template

D

dgront

Maybe my question is too simple, but I've spent some time on it and
still don't know..

I need a template function, converting from string to other data types:
template <typename T> converter(std::string s);

For T = double, int, etc. it works fine. But how to do it for a type
which already is a template, like

template<typename T> class Point { T x, y,z; };
template<typename T> class AnotherClass { T data; };

How to make converter working both for Point<T>, AnotherClacc<T>,
double, int, etc...?

Dominik
 
V

Victor Bazarov

dgront said:
Maybe my question is too simple, but I've spent some time on it and
still don't know..

I need a template function, converting from string to other data types:
template <typename T> converter(std::string s);

You mean,

template<typename T> T converter(std::string const& s);

, don't you?
For T = double, int, etc. it works fine. But how to do it for a type
which already is a template,

There is no such thing. It's either a type or a template.
like

template<typename T> class Point { T x, y,z; };
template<typename T> class AnotherClass { T data; };

How to make converter working both for Point<T>, AnotherClacc<T>,
double, int, etc...?

How do you plan on using it?

V
 
R

rod

A way I got this to work is as follows:

template< template<typename U> class T >
void converter(string & sName)
{
T<typename> nVar;
sName = nVar.toString(); \\ or whatever string conversion function
}
 
V

Victor Bazarov

rod said:
A way I got this to work is as follows:

template< template<typename U> class T >
void converter(string & sName)
'void'?

{
T<typename> nVar;
sName = nVar.toString(); \\ or whatever string conversion function
}

So, how does the value get back? And how do you see it used?
 
R

rod

Sorry I was working the other way around. Try this:

template< template<typename U> class T >
T<typename> converter(const string & sData)
{
T<typename> nVar;
nVar.fromString(sData);
return nVar;
}
 
R

rod

Sorry I was converting the other way around. Try this:

template< template<typename U> class T >
T<typename> converter(const string & sData)
{
T<typename> nVar;
nVar.fromString(sData);
return nVar;
}
 
V

Victor Bazarov

rod said:
Sorry I was working the other way around. Try this:

template< template<typename U> class T >
T<typename> converter(const string & sData)
{
T<typename> nVar;
nVar.fromString(sData);
return nVar;
}

Uh... Doesn't seem to work. Here's a complete program, please make
it compile with Comeau online:

#include <string>
#include <sstream>

template<class T> class Point {
public:
T x,y,z;
void fromString(std::string const& s) {
std::istringstream is(s);
is >> x >> y >> z;
}
};

template< template<typename U> class T >
T<typename> converter(const std::string & sData)
{
T<typename> nVar;
nVar.fromString(sData);
return nVar;
}

int main()
{
Point<double> pd;
pd = converter<Point>("1.0 2.0 3.0"); // I am guessing here ???

return 0;
}
 
D

Daniel T.

dgront said:
Maybe my question is too simple, but I've spent some time on it and
still don't know..

I need a template function, converting from string to other data types:
template <typename T> converter(std::string s);

For T = double, int, etc. it works fine. But how to do it for a type
which already is a template, like

template<typename T> class Point { T x, y,z; };
template<typename T> class AnotherClass { T data; };

How to make converter working both for Point<T>, AnotherClacc<T>,
double, int, etc...?


I suggest you use boost's lexical_cast.

Point p = lexical_cast<Point>( myStringRep );

Below is a rough version, the boost version is much more robust.

template < typename T, typename U >
T lexical_cast( const U& arg ) {
std::stringstream ss;
T result;

if ( !( ss << arg && ss >> result ) )
throw std::exception();
return result;
}
 
R

rod

That code worked fine for me on VC7.1 but did not on Comeau. The only
way I've got this to work is as follows (which is not necessarily the
way you wanted to use it):

#include <string>
#include <sstream>

template<class T>
class Point
{
public:
T x,y,z;

void fromString(const std::string & s)
{
std::istringstream is(s);
is >> x >> y >> z;
}

void outputString()
{
std::cout << x << " " << y << " " << z << std::endl;
}
};

template< class T >
T converter(const std::string & sData)
{
T nVar;
nVar.fromString(sData);
return nVar;
}

int main()
{
Point<double> pd;
pd = converter< Point<double> >("1.0 2.0 3.0"); // I am guessing here
???
pd.outputString();
return 0;
}
 
V

Victor Bazarov

rod said:
That code worked fine for me on VC7.1 but did not on Comeau. The only
way I've got this to work is as follows (which is not necessarily the
way you wanted to use it):

[...]
template< class T >
T converter(const std::string & sData)
{
T nVar;
nVar.fromString(sData);

Sure. But going back to the OP's question, how do you make it work with
built-in types now? They don't have 'fromString' member functions, do
they?
return nVar;
}


V
 
V

Victor Bazarov

Daniel said:
I suggest you use boost's lexical_cast.

Point p = lexical_cast<Point>( myStringRep );

'Point' is not a class. It's a template.
Below is a rough version, the boost version is much more robust.

template < typename T, typename U >
T lexical_cast( const U& arg ) {
std::stringstream ss;
T result;

if ( !( ss << arg && ss >> result ) )
throw std::exception();
return result;
}

V
 
R

rod

One way would be to use template specialization...one for each built-in
type you want to convert a string to:

template<>
double converter(const std::string & sData)
{
// Code that converts a string to a double
}

.....
 
R

rod

One way would be to use template specialization for each built-in type
you wanted to convert to from a string, i.e:

template<>
double converter(const std::string & sData)
{
// Code that converts to a double
}
 

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
474,202
Messages
2,571,055
Members
47,658
Latest member
jaguar32

Latest Threads

Top