C++: Undefined symbols for architecture x86_64:

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Prelates, Moderators General

C++: Undefined symbols for architecture x86_64:

Postby DanB91 » Fri Dec 30, 2011 12:05 am UTC

I am trying to write a utility class (named "Utility" which is in Utility.cpp/.h) that will contain all static methods. One of these methods will be a "fromString" method which is a templated method that takes a string and outputs an object (normally a primitive). For some reason whenever I try to compile, it gives the error "Undefined symbols for architecture x86_64:
"int Utility::fromString<int>(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)" ".

Utility.o is in the makefile and I do include Utility.h in the class where I am calling the function, so these are not the issues. There are no other compile errors (i.e. .cpp files compile fine). I did notice that when I make the method NOT templated, it compiles. I am a bit new to C++ (coming from C and Java) Here is the code:

Code: Select all
//Utility.h


#ifndef UTIL_H
#define UTIL_H

#include <sstream>


using namespace std;


class Utility{


   public:
      //takes a string and casts it to an object
      template<typename T> static T fromString(const string& s);
      
};

#endif



Code: Select all
//Utility.cpp
#include "Utility.h"
#include <sstream>

using namespace std;


/*
 * This method takes in a string and outputs the object (normally a primitive) representing it
 */
 
template<typename T> T Utility::fromString(const string& s)
{
   istringstream iss(s);
   T ret;

   iss >> ret;

   return ret;

   

}


Code: Select all

//caller
int num = Utility::fromString<int>(numStr);



DanB91
 
Posts: 11
Joined: Fri Nov 26, 2010 5:01 pm UTC

Re: C++: Undefined symbols for architecture x86_64:

Postby Laguana » Fri Dec 30, 2011 12:42 am UTC

The solution here is that you need to have the definition of the templated function in the header file, not just the declaration. This is a limitation of C++'s templating system.

My understanding is that templated code is compiled as-required at compilation time (not link-time), so your utility.o won't include an int-instantiated version of the fromString method unless something else in that same compilation unit needs it. This means that when other code tries to link with fromString<int> in utility.o, it can't find it.
Laguana
 
Posts: 49
Joined: Sat Jan 19, 2008 10:13 pm UTC

Re: C++: Undefined symbols for architecture x86_64:

Postby DanB91 » Fri Dec 30, 2011 2:52 am UTC

Laguana wrote:The solution here is that you need to have the definition of the templated function in the header file, not just the declaration. This is a limitation of C++'s templating system.

My understanding is that templated code is compiled as-required at compilation time (not link-time), so your utility.o won't include an int-instantiated version of the fromString method unless something else in that same compilation unit needs it. This means that when other code tries to link with fromString<int> in utility.o, it can't find it.


Ah, interesting (and disappointing). Thanks very much!
DanB91
 
Posts: 11
Joined: Fri Nov 26, 2010 5:01 pm UTC

Re: C++: Undefined symbols for architecture x86_64:

Postby EvanED » Fri Dec 30, 2011 4:42 am UTC

In terms of code organization, you still can separate interface from implementation. What you do is put the implementation of Utility::fromString() into some file which you then #include from the header.

I've seen a couple conventions for what to call that implementation file; I suggest picking a consistent one. For instance, I've worked on a project which has put the interface in blah.hpp, template definitions in blah_impl.hpp, and non-template implementations of course in blah.cpp. I've also heard of using blah.tpp for the second set of files; I really like the idea in theory but haven't tried it out to see how easy it is to get typical tools to recognize .tpp as a header file.

Finally, one convention I've seen and highly recommend you avoid is keep the file organization you have above, but then #include blah.cpp from blah.hpp. This has a bunch of drawbacks and can be a PITA to deal with. (For instance, you can no longer really figure out what files you have to actually compile simply by looking at the file name. You have to actually open it up and see whether it contains template definitions. Also, it means that if a header has both template and non-template stuff in it, then the second and third categories above collapse because you only have two files. Which means every non-template function has to be inline and yadda yadda yadda.)
EvanED
 
Posts: 4141
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI

Re: C++: Undefined symbols for architecture x86_64:

Postby Yakk » Fri Dec 30, 2011 4:52 am UTC

Note that at least 1 C++ compiler (Comeau) supports the export template syntax, which (basically) supports doing what you are asking to be done. It was considered for inclusion in C++0x, but removed before the standard was finalized.

Next, note that using classes as namespaces in C++ is not all that required. You can just create functions in a namespace, instead of sticking them in a class. There are reasons to use classes as namespaces (such as the ability to template classes, but not namespaces), but there are also reasons not to (the using keyword, for example, works with namespaces, but less so with classes ...)

One way to understand what needs to be exposed in a header vs a cpp file in standard C++ is thinking "would a fixed binary function, with no ability to extend to new types, be able to handle this?" If so, it can go in a .cpp file. This can also help you understand when you can do a workaround -- when and how you can "bundle" the problem up in a class and sneak it into a .cpp file implementation and out of header files.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.
User avatar
Yakk
Poster with most posts but no title.
 
Posts: 10450
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: C++: Undefined symbols for architecture x86_64:

Postby EvanED » Fri Dec 30, 2011 5:39 am UTC

Yakk wrote:Note that at least 1 C++ compiler (Comeau) supports the export template syntax, which (basically) supports doing what you are asking to be done. It was considered for inclusion in C++0x, but removed before the standard was finalized.

Your story with respect to the standard is a bit off. export is part of C++98, having been added before anyone implemented it (or really, thought through the consequences very well). It was actually removed from C++11.

And it's only supported in a couple, less popular compilers; as Yakk mentioned, Comeau supports it, Intel has some support supposedly, and Wikipedia says Borland C++ Builder X has some support. (The common thread is that all three use the EDG front end.) Neither GCC nor MSVC support it, nor will they even with any remotely reasonable probability now that it's no longer in the latest standard.
EvanED
 
Posts: 4141
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI


Return to Coding

Who is online

Users browsing this forum: No registered users and 5 guests