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

template function problem

P: n/a
Dear all,

I have the following code:

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

using namespace std;

int str_to_int (const string str)
{
istringstream str_s (str);
int num;
str_s >num;
return num;
}

template <typename T>
string num_to_str (const T num)
{
ostringstream o_str;
o_str << num;
return o_str.str();
}

int main (void)
{
int i = 3, j = 5;
string str = num_to_str (j);
i += str_to_int (str);
cout << i << endl;
getchar();
return 0;
}

As you can see from the function "num_to_str", it has been tested with
various numeric data types such as short, float, double, ..etc. and it
works just fine.
However, the function "str_to_int" can also be replaced with
"str_to_float", "str_to_double" and so third and so fourth with just
replacing the int to float, int to double, ..etc.
So i thought of making it a template function as well and changed the
function "str_to_int" into:

template <typename T>
T str_to_num (const string str)
{
istringstream str_s (str);
T num;
str_s >num;
return num;
}
but i get the following error:
28 no matching function for call to `str_to_num(std::string&)'

Can any one see what's wrong?

Oct 1 '06 #1
Share this Question
Share on Google+
8 Replies


P: n/a
In article <11**********************@h48g2000cwc.googlegroups .com>,
"coosa" <co*****@gmail.comwrote:
Dear all,

I have the following code:

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

using namespace std;

int str_to_int (const string str)
{
istringstream str_s (str);
int num;
str_s >num;
return num;
}

template <typename T>
string num_to_str (const T num)
{
ostringstream o_str;
o_str << num;
return o_str.str();
}

int main (void)
{
int i = 3, j = 5;
string str = num_to_str (j);
i += str_to_int (str);
cout << i << endl;
getchar();
return 0;
}

As you can see from the function "num_to_str", it has been tested with
various numeric data types such as short, float, double, ..etc. and it
works just fine.
However, the function "str_to_int" can also be replaced with
"str_to_float", "str_to_double" and so third and so fourth with just
replacing the int to float, int to double, ..etc.
So i thought of making it a template function as well and changed the
function "str_to_int" into:

template <typename T>
T str_to_num (const string str)
{
istringstream str_s (str);
T num;
str_s >num;
return num;
}
but i get the following error:
28 no matching function for call to `str_to_num(std::string&)'

Can any one see what's wrong?
You need to tell it, at the place it is being called, what type to
convert to. As in:

double d = str_to_num<double>( myString );

--
There are two things that simply cannot be doubted, logic and perception.
Doubt those, and you no longer*have anyone to discuss your doubts with,
nor any ability to discuss them.
Oct 1 '06 #2

P: n/a

Daniel T. wrote:
In article <11**********************@h48g2000cwc.googlegroups .com>,
"coosa" <co*****@gmail.comwrote:
Dear all,

I have the following code:

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

using namespace std;

int str_to_int (const string str)
{
istringstream str_s (str);
int num;
str_s >num;
return num;
}

template <typename T>
string num_to_str (const T num)
{
ostringstream o_str;
o_str << num;
return o_str.str();
}

int main (void)
{
int i = 3, j = 5;
string str = num_to_str (j);
i += str_to_int (str);
cout << i << endl;
getchar();
return 0;
}

As you can see from the function "num_to_str", it has been tested with
various numeric data types such as short, float, double, ..etc. and it
works just fine.
However, the function "str_to_int" can also be replaced with
"str_to_float", "str_to_double" and so third and so fourth with just
replacing the int to float, int to double, ..etc.
So i thought of making it a template function as well and changed the
function "str_to_int" into:

template <typename T>
T str_to_num (const string str)
{
istringstream str_s (str);
T num;
str_s >num;
return num;
}
but i get the following error:
28 no matching function for call to `str_to_num(std::string&)'

Can any one see what's wrong?

You need to tell it, at the place it is being called, what type to
convert to. As in:

double d = str_to_num<double>( myString );

--
There are two things that simply cannot be doubted, logic and perception.
Doubt those, and you no longer have anyone to discuss your doubts with,
nor any ability to discuss them.
Thanks alot, it worked; i just thought that specifying the type is only
required by class templates and not function templates!

Oct 1 '06 #3

P: n/a
Daniel T. wrote:
In article <11**********************@h48g2000cwc.googlegroups .com>,
"coosa" <co*****@gmail.comwrote:
Dear all,

I have the following code:

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

using namespace std;

int str_to_int (const string str)
{
istringstream str_s (str);
int num;
str_s >num;
return num;
}

template <typename T>
string num_to_str (const T num)
{
ostringstream o_str;
o_str << num;
return o_str.str();
}

int main (void)
{
int i = 3, j = 5;
string str = num_to_str (j);
i += str_to_int (str);
cout << i << endl;
getchar();
return 0;
}

As you can see from the function "num_to_str", it has been tested with
various numeric data types such as short, float, double, ..etc. and it
works just fine.
However, the function "str_to_int" can also be replaced with
"str_to_float", "str_to_double" and so third and so fourth with just
replacing the int to float, int to double, ..etc.
So i thought of making it a template function as well and changed the
function "str_to_int" into:

template <typename T>
T str_to_num (const string str)
{
istringstream str_s (str);
T num;
str_s >num;
return num;
}
but i get the following error:
28 no matching function for call to `str_to_num(std::string&)'

Can any one see what's wrong?

You need to tell it, at the place it is being called, what type to
convert to. As in:

double d = str_to_num<double>( myString );

--
There are two things that simply cannot be doubted, logic and perception.
Doubt those, and you no longer have anyone to discuss your doubts with,
nor any ability to discuss them.
By the way, shouldn't the same apply to the function "num_to_str" as:
string str = num_to_str <int(j); ?
but it works fine with: string str = num_to_str (j);

Oct 1 '06 #4

P: n/a
"coosa" <co*****@gmail.comwrote:
By the way, shouldn't the same apply to the function "num_to_str" as:
string str = num_to_str <int(j); ?
but it works fine with: string str = num_to_str (j);
No, the same doesn't apply because the compiler can infer the type by
looking at the parameter's type.

You could set your function up like iostream's op>and then you
wouldn't have to specify the type.

template < typename T >
void string_to_num( const string& str, T& num )
{
//...
}

Now you would call it like:

double d;
string_to_num( myString, d );

--
There are two things that simply cannot be doubted, logic and perception.
Doubt those, and you no longer*have anyone to discuss your doubts with,
nor any ability to discuss them.
Oct 1 '06 #5

P: n/a

Daniel T. wrote:
"coosa" <co*****@gmail.comwrote:
By the way, shouldn't the same apply to the function "num_to_str" as:
string str = num_to_str <int(j); ?
but it works fine with: string str = num_to_str (j);

No, the same doesn't apply because the compiler can infer the type by
looking at the parameter's type.

You could set your function up like iostream's op>and then you
wouldn't have to specify the type.

template < typename T >
void string_to_num( const string& str, T& num )
{
//...
}

Now you would call it like:

double d;
string_to_num( myString, d );

--
There are two things that simply cannot be doubted, logic and perception.
Doubt those, and you no longer have anyone to discuss your doubts with,
nor any ability to discuss them.
Ok Daniel,
Thanks for the help so far; I'd like to disturb you a little more! :-)
Have a look at this header file:

//Begin of File converter.hpp
#ifndef converterHPP
#define converterHPP

#include <iostream>

using namespace std;

namespace convert
{
class string
{
public:
template <typename T>
static T to_number (string);
};

class number
{
public:
template <typename T>
static string to_string (T);
};
}

#endif
//End of File converter.hpp

and then at this source file:

//Begin of File converter.cpp
#include "converter.hpp"
#include <sstream>

using namespace std;

namespace convert
{
template <typename T>
T string::to_number (string str)
{
T num;
istringstream str_s (str);
str_s >num;
return num;
}

template <typename T>
string number::to_string (T num)
{
ostringstream o_str;
o_str << num;
return o_str.str();
}
}
//End of File converter.cpp

and finally at this mail file:

//Begin of File main.cpp
#include "converter.hpp"
#include <cstdlib>
#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{
float f1 = 3.4;
int i1 = 5;
string s1 = "7.023";
double d1 = 12345.80346;
float f2 = convert::string::to_number <float(s1); // causes error
string s2 = convert::number::to_string <double(d1); //causes
error
system("PAUSE");
return EXIT_SUCCESS;
}
//End of File main.cpp

I get the folllowing error log

Compiler: Default compiler
Building Makefile: "C:\Dokumente und
Einstellungen\Administrator\Desktop\test3\Makefile .win"
Executing make...
make.exe -f "C:\Dokumente und
Einstellungen\Administrator\Desktop\test3\Makefile .win" all
g++.exe -D__DEBUG__ -c main.cpp -o main.o
-I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"
-I"C:/Dev-Cpp/include/c++/3.4.2/backward"
-I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"
-I"C:/Dev-Cpp/include/c++/3.4.2" -I"C:/Dev-Cpp/include" -g3

main.cpp: In function `int main(int, char**)':

main.cpp:14: error: no matching function for call to
`convert::string::to_number(std::string&)'
converter.hpp:14: note: candidates are: static T
convert::string::to_number(convert::string) [with T = float]

main.cpp:15: error: conversion from `convert::string' to non-scalar
type `std::basic_string<char, std::char_traits<char>,
std::allocator<char' requested

make.exe: *** [main.o] Error 1

Execution terminated

Could you please check it out and tell me what's wrong in the code?

Best regards

Oct 1 '06 #6

P: n/a
coosa schrieb:
Have a look at this header file:

//Begin of File converter.hpp
#ifndef converterHPP
#define converterHPP

#include <iostream>

using namespace std;

namespace convert
{
class string
{
public:
template <typename T>
static T to_number (string);
};

class number
{
public:
template <typename T>
static string to_string (T);
};
}
The problem is, that you declare a class named string and use a string as
parameter, which should be std::string but instead refers to your string class.

So my advice:
1) _never_ put "using namespace std;" in a header file.
2) don't name your own classes like standard library classes.

Make it string_to_number() or just toString() and fromString().

Also, take a look at the FAQ:
http://www.parashift.com/c++-faq-lit...al-issues.html

--
Thomas
http://www.netmeister.org/news/learn2quote.html
Oct 1 '06 #7

P: n/a
"coosa" <co*****@gmail.comwrote:

The error in your code has to do with the 'string' class you have
created in your header file. You are using std::string in your main
function, but convert::string in your 'convert' namespace.

Notes in the code:
Ok Daniel,
Thanks for the help so far; I'd like to disturb you a little more! :-)
Have a look at this header file:

//Begin of File converter.hpp
#ifndef converterHPP
#define converterHPP

#include <iostream>

using namespace std;
Don't put using declarations in headers, qualify each name instead.
>
namespace convert
{
class string
{
public:
template <typename T>
static T to_number (string);
};
Above you created your own string class "convert::string". Now the
compiler is assuming that any reference to "string" within this
namespace is really a reference to "convert::string" and not
"std::string".

Also, templated functions should be defined in the header file so the
definition is available at all points of use.
class number
{
public:
template <typename T>
static string to_string (T);
};
Above you created a class called 'number'. I get the impression you are
coming from Java? You don't need to put static functions inside classes.
}

#endif
//End of File converter.hpp
Try this for a header file instead:

#ifndef converterHPP
#define converterHPP

#include <iostream>

template < typename T >
T to_number( const std::string& s ) {
T result;
std::istringstream iss( s );
iss >result; // what if this fails?
// Currently the result will be undefined.
return result;
}

template < typename T >
std::string to_string( const T& val ) {
std::string result;
std::ostringstream oss;
oss << val; // what if this fails?
return oss.str();
}

#endif // converterHPP
and then at this source file:

//Begin of File converter.cpp
#include "converter.hpp"
#include <sstream>

using namespace std;

namespace convert
{
template <typename T>
T string::to_number (string str)
{
T num;
istringstream str_s (str);
str_s >num;
return num;
}

template <typename T>
string number::to_string (T num)
{
ostringstream o_str;
o_str << num;
return o_str.str();
}
}
//End of File converter.cpp
The above assumes convert::string for both references to 'string'. Your
code won't work with std::string as a result.
and finally at this mail file:

//Begin of File main.cpp
#include "converter.hpp"
#include <cstdlib>
#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{
float f1 = 3.4;
int i1 = 5;
string s1 = "7.023";
double d1 = 12345.80346;
float f2 = convert::string::to_number <float(s1); // causes error
Your attempting to pass in a std::string instead of a convert::string.
string s2 = convert::number::to_string <double(d1); //causes
error
Your attempting to assign a convert::string to a std::string, but have
defined no way to do that.
system("PAUSE");
return EXIT_SUCCESS;
}
//End of File main.cpp

I get the folllowing error log

main.cpp:14: error: no matching function for call to
`convert::string::to_number(std::string&)'
The compiler can't find the above function, because one doesn't exist.
converter.hpp:14: note: candidates are: static T
convert::string::to_number(convert::string) [with T = float]
The above is what you do have (note "convert::string" inside the parens
instead of "std::string".)
main.cpp:15: error: conversion from `convert::string' to non-scalar
type `std::basic_string<char, std::char_traits<char>,
std::allocator<char' requested
And here, the compiler says you are trying to convert from a
"convert::string" to a "std::string" (which is a typedef for
"std::basic_string<char, std::char_traits<char>, std::allocator<char.)

--
There are two things that simply cannot be doubted, logic and perception.
Doubt those, and you no longer*have anyone to discuss your doubts with,
nor any ability to discuss them.
Oct 1 '06 #8

P: n/a

Daniel T. wrote:
"coosa" <co*****@gmail.comwrote:

The error in your code has to do with the 'string' class you have
created in your header file. You are using std::string in your main
function, but convert::string in your 'convert' namespace.

Notes in the code:
Ok Daniel,
Thanks for the help so far; I'd like to disturb you a little more! :-)
Have a look at this header file:

//Begin of File converter.hpp
#ifndef converterHPP
#define converterHPP

#include <iostream>

using namespace std;

Don't put using declarations in headers, qualify each name instead.

namespace convert
{
class string
{
public:
template <typename T>
static T to_number (string);
};

Above you created your own string class "convert::string". Now the
compiler is assuming that any reference to "string" within this
namespace is really a reference to "convert::string" and not
"std::string".

Also, templated functions should be defined in the header file so the
definition is available at all points of use.
class number
{
public:
template <typename T>
static string to_string (T);
};

Above you created a class called 'number'. I get the impression you are
coming from Java? You don't need to put static functions inside classes.
}

#endif
//End of File converter.hpp

Try this for a header file instead:

#ifndef converterHPP
#define converterHPP

#include <iostream>

template < typename T >
T to_number( const std::string& s ) {
T result;
std::istringstream iss( s );
iss >result; // what if this fails?
// Currently the result will be undefined.
return result;
}

template < typename T >
std::string to_string( const T& val ) {
std::string result;
std::ostringstream oss;
oss << val; // what if this fails?
return oss.str();
}

#endif // converterHPP
and then at this source file:

//Begin of File converter.cpp
#include "converter.hpp"
#include <sstream>

using namespace std;

namespace convert
{
template <typename T>
T string::to_number (string str)
{
T num;
istringstream str_s (str);
str_s >num;
return num;
}

template <typename T>
string number::to_string (T num)
{
ostringstream o_str;
o_str << num;
return o_str.str();
}
}
//End of File converter.cpp

The above assumes convert::string for both references to 'string'. Your
code won't work with std::string as a result.
and finally at this mail file:

//Begin of File main.cpp
#include "converter.hpp"
#include <cstdlib>
#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{
float f1 = 3.4;
int i1 = 5;
string s1 = "7.023";
double d1 = 12345.80346;
float f2 = convert::string::to_number <float(s1); // causes error

Your attempting to pass in a std::string instead of a convert::string.
string s2 = convert::number::to_string <double(d1); //causes
error

Your attempting to assign a convert::string to a std::string, but have
defined no way to do that.
system("PAUSE");
return EXIT_SUCCESS;
}
//End of File main.cpp

I get the folllowing error log

main.cpp:14: error: no matching function for call to
`convert::string::to_number(std::string&)'

The compiler can't find the above function, because one doesn't exist.
converter.hpp:14: note: candidates are: static T
convert::string::to_number(convert::string) [with T = float]

The above is what you do have (note "convert::string" inside the parens
instead of "std::string".)
main.cpp:15: error: conversion from `convert::string' to non-scalar
type `std::basic_string<char, std::char_traits<char>,
std::allocator<char' requested

And here, the compiler says you are trying to convert from a
"convert::string" to a "std::string" (which is a typedef for
"std::basic_string<char, std::char_traits<char>, std::allocator<char.)

--
There are two things that simply cannot be doubted, logic and perception.
Doubt those, and you no longer have anyone to discuss your doubts with,
nor any ability to discuss them.
Thanks alot, that was very helpful,

I do like java alot indeed, but i started learning C++ before Java;
it's just that i didn't tough C++ for quite some time, so my brain have
got rusted! :-)

Oct 1 '06 #9

This discussion thread is closed

Replies have been disabled for this discussion.