473,320 Members | 1,817 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,320 software developers and data experts.

Strange linking error with template

Hello,

I have a simple program to create strings from the corresponding
double/integer values. For any data type similar to int, I have a
template set up in a file misc.h:

************************************************** ***********************************
//misc.h
#ifndef __MISC_H__
#define __MISC_H__

#include <string>

//!Convert any numerical quantity (int, long, uint*_t, time_t, etc) to
a string
template <class X> string numtostr(X number);
//I have explicitly overloaded it for double:
//!Convert a double to a string
string numtostr(double number);

#endif
I have their corresponding bodies in the file misc.cpp. In test.cpp ,
I have the main() function (quite simple - see below).

************************************************** *********************************
//test.cpp
#include <iostream>
#include <string>

#include "misc.h"

using namespace std;
int main()
{
int a=30;

cout<<numtostr(a)<<endl;

return 0;
}

************************************************** **********************************
//misc.cpp
#include <iostream>
#include <cstdlib>
#include <string>
#include <vector>

#include "misc.h"

using namespace std;

template <class X> string numtostr(X number)
{
//get the length of the string
char junk;
size_t len = snprintf(&junk,1,"%d",number);

//temporary buffer to hold the string
vector<char> temp(len);
sprintf(&(temp.at(0)), "%d",number);
//put the data in the string
string result(temp.begin(), temp.end());

return result;
}

string numtostr(double number)
{
//get the length of the string
char junk;
size_t len = snprintf(&junk,1,"%f",number);

//temporary buffer to hold the string
vector<char> temp(len);
sprintf(&(temp.at(0)), "%f",number);

//put the data in the string
string result(temp.begin(), temp.end());

return result;
}
************************************************** ************************************
When I try to compile this program using "g++ -o test test.cpp
misc.cpp", I get the following error:

/tmp/cc6tDQzg.o: In function `main':
test.cpp:(.text+0x18): undefined reference to `std::basic_string<char,
std::char_traits<char>, std::allocator<char> > numtostr<int>(int)'
collect2: ld returned 1 exit status

I'm not sure why it's unable to find that template. If in main(), I
change it to float a=35.5; then it works perfectly!

I also tried to put everything in just one file. And then when I tried
to compile it, it works fine for both int and double!

I'm completely at a loss as to what is happening. Your help will be
appreicated! Just for some more details, g++ --version gives:

g++ (GCC) 4.0.1 (Debian 4.0.1-2)
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is
NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.
Thanks,
Jimmy

Oct 12 '05 #1
5 1667
In article <11**********************@g49g2000cwa.googlegroups .com>,
sleepydj <de********@gmail.com> wrote:
//misc.h ....
template <class X> string numtostr(X number);
...
I have their corresponding bodies in the file misc.cpp. In test.cpp ,
I have the main() function (quite simple - see below).
....
When I try to compile ... I get the following error:

/tmp/cc6tDQzg.o: In function `main':
test.cpp:(.text+0x18): undefined reference to `std::basic_string<char,
std::char_traits<char>, std::allocator<char> > numtostr<int>(int)'
collect2: ld returned 1 exit status
...


See http://www.comeaucomputing.com/techt.../#whylinkerror
--
Greg Comeau / Celebrating 20 years of Comeauity!
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Oct 12 '05 #2
Hi,

Oh I managed to figure it out (thanks to a friend!). Apparently, the
template function body must always be defined in the header file. The
reason being that template functions are actually expanded for each
data type by the compiler. The cpp file is only compiled once whereas
the header file is compiled as many times as it is included. So when
the template function is defined in the header file, it allows the
compiler to customize it to every data type as many times as necessary!

I hope that is the right explanation (and that it makes sense!)

Thanks,
Jimmy

Oct 12 '05 #3
Hey Greg,

Looks like you beat me to it! :)

Thanks,
Jimmy

Oct 12 '05 #4
Ian
sleepydj wrote:
Hi,

Oh I managed to figure it out (thanks to a friend!). Apparently, the
template function body must always be defined in the header file. The
reason being that template functions are actually expanded for each
data type by the compiler. The cpp file is only compiled once whereas
the header file is compiled as many times as it is included. So when
the template function is defined in the header file, it allows the
compiler to customize it to every data type as many times as necessary!

I hope that is the right explanation (and that it makes sense!)

It is for compilers that require the bodies to be visible in the header.
Some do, some don't.

Ian
Oct 12 '05 #5

"sleepydj" <de********@gmail.com> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...
| Hello,
|
| I have a simple program to create strings from the corresponding
| double/integer values. For any data type similar to int, I have a
| template set up in a file misc.h:
|
|
************************************************** **********************
*************
| //misc.h
| #ifndef __MISC_H__
| #define __MISC_H__
|
| #include <string>
|
| //!Convert any numerical quantity (int, long, uint*_t, time_t, etc) to
| a string
| template <class X> string numtostr(X number);

there is no such type called "string", try a std::string.

something like:

template< class N >
std::string numtostr(N n);

|
|
| //I have explicitly overloaded it for double:
| //!Convert a double to a string
| string numtostr(double number);

the proper term is a template "specialization":

template<>
std::string numtostr< double >(double d);

<snip>

| //misc.cpp
| #include <iostream>
| #include <cstdlib>
| #include <string>
| #include <vector>
|
| #include "misc.h"
|
| using namespace std;
|
| template <class X> string numtostr(X number)
| {
| //get the length of the string
| char junk;
| size_t len = snprintf(&junk,1,"%d",number);
|
| //temporary buffer to hold the string
| vector<char> temp(len);
| sprintf(&(temp.at(0)), "%d",number);
|
|
| //put the data in the string
| string result(temp.begin(), temp.end());
|
| return result;
| }

<snip>

|
| I also tried to put everything in just one file. And then when I tried
| to compile it, it works fine for both int and double!
|

in the case you prefer not seperating the interface and
implementation...

#include <string>
#include <sstream>

template< class N >
std::string TtoString(N n)
{
ostringstream oss;
oss << n;
return oss.str();
}

stringstreams are worth learning...

<snip>

In the case you decide to seperate header and source, try using template
specialization...

---
// Misc.h

#ifndef MISC_H_
#define MISC_H_

#include <string>

template< class N >
std::string numtostr(N n);

template<>
std::string numtostr< int >(int n);

template<>
std::string numtostr< double >(double d);

template<>
std::string numtostr< long >(long d);

#endif // MISC_H_
---
// Misc.cpp
#include "Misc.h"
#include <iostream>
#include <sstream>
using std::string;
using std::ostringstream;

template<>
string numtostr< int >(int n)
{
ostringstream oss;
oss << n;
return oss.str();
}

template<>
string numtostr< double >(double d)
{
ostringstream oss;
oss << d;
return oss.str();
}

template<>
string numtostr< long >(long l)
{
ostringstream oss;
oss << l;
return oss.str();
}
---
// test.cpp
#include "Misc.h"
#include <iostream>
#include <string>

int main()
{
std::string s;

int n(-11);
s += numtostr(n);
s += ", ";

double d(11.1111);
s += numtostr(d);
s += ", ";

long l(1111);
s += numtostr(l);

std::cout << "the sequence of numbers is: ";
std::cout << s << std::endl;

return 0;
}

/* output:

the sequence of numbers is: -11, 11.1111, 1111

*/
Oct 12 '05 #6

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

Similar topics

1
by: Tobias Langner | last post by:
I try to program a smart-pointer using policies. I rely heavyly on templates during this. The program compiles fine - but I get a linker error: test.o(.text+0x3e): In function `testSmartPtr()':...
5
by: Yoon-Soo Lee | last post by:
I am using Visual C++ .NET 2003 and running into some linking error from the following template code. The error messages is error LNK2019: unresolved external symbol "class...
2
by: Avi Uziel | last post by:
Hi All, I have a linkage problem that I believe related to template instantiation. My environment is Solaris 5.6, Compiler WorkShop 5. I'm building a shared library which use templates. During...
15
by: Rob Ratcliff | last post by:
I'm compiling the latest version of a CORBA ORB called MICO on a Cray X1. It makes heavy use of templates and namespaces. Up until the link step, the C++ source code compiled flawlessly. But, when...
15
by: Improving | last post by:
I have a template class that has static members, so in the .cpp file I have defined them with templated definitions. Now when in a different ..cpp file that includes the header file for the...
4
by: Gary Hughes | last post by:
Hi all, sometime I posted a problem in here where I was getting the following error from the linker in VS C++ 2003. Linking... GCClass.obj : error LNK2022: metadata operation failed (80131188)...
2
by: .NET developer | last post by:
Hi , While upgrading my application from vc6 to vc7 I got followin linking errors : __declspec(dllimport) public: class ATL::CStringT<unsigned short,class StrTraitMFC_DLL<unsigned short,class...
1
by: stromhau | last post by:
Ok, i have a file with main and an additional .cpp file i include in the main file but i get a lot of strange warnings when including. Both files compile just great separately. It seems that it have...
9
by: Peskov Dmitry | last post by:
It is a very basic question.Surely i got something wrong in my basic understanding. //Contents of file1.cpp using namespace std; #include <iostream> template <typename T> class my_stack;
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

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.