Hello again, i ran into some trouble with Visual C++ 2008 when i tried to use a template function. I only get this error when i try to use the function from main().

I used another template function succesfully earlier, but i can not figure out what is wrong with this one.

Any help is appreciated.:)


This is the error message i receive :P

error LNK2019: unresolved external symbol "void __cdecl split2<class std::back_insert_iterator<class std::list<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > > >(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::back_insert_iterator<class std::list<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > >)" (??$split2@V?$back_insert_iterator@V?$list@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@@std@@@@YAXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$back_insert_iterator@V?$list@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@@1@@Z) referenced in function _main

This is part of my *.h file:

template <class Out>
void split2(const std::string&, Out);

And this is is part of my *.cpp file:

template <class Out>
void split2(const string& str, Out os) {

	typedef string::const_iterator iter;
	iter i = str.begin();
	while (i != str.end()) {

		// ignore leading blanks
		i = find_if(i, str.end(), not_space);

		// find end of next word
		iter j = find_if(i, str.end(), space);

		// copy the characters in [i, j)
		if (i != str.end())
			*os++ = string(i, j); // changed
		i = j;
	}
}

Edit: This is an example of how i want to use it in main():

string s;
	while (getline(cin, s))
		split2(s, ostream_iterator<string>(cout, "\n"));

Dani AI

Generated

As observed, the linker message here is the classic sign that a template definition wasn't available at the point the compiler generated (or expected) the instantiation. The mangled linker line actually reveals the exact instantiation the linker wants — in this case the split2 overload for a back_insert_iterator<list<string>> — which is useful when deciding how to resolve the missing symbol. 's FAQ pointer is a good next-step for background on why templates follow the inclusion model.

Two practical ways to fix this in a multi-file project:

  • Keep the template implementation visible where it’s used (common patterns: put the implementation in the header, or in a small .ipp/.inl file that the header #includes at the end). This makes the compiler instantiate the template in every translation unit that needs it and avoids link errors.
  • Or, if only a limited set of concrete types is ever required, explicitly instantiate the template in the .cpp that contains the implementation so the symbol exists at link time. For example:
template void split2<std::back_insert_iterator<std::list<std::string>>>(
    const std::string&, std::back_insert_iterator<std::list<std::string>>);

Quick troubleshooting checklist (common causes of LNK2019 with templates): confirm the declaration/definition signatures match exactly (const/ref qualifiers, typedefs/aliases and namespaces), verify the header with the definition is actually included where needed, and ensure the project is linking the object/library that contains any explicit instantiations. For distribution or large projects, prefer the header-inclusion pattern for correctness; use explicit instantiation to reduce compile-time cost when the set of types is small and known.

Recommended Answers

All 3 Replies

The problem is (most likely) that you have to define a template function in the same file where it is declared. For a good over-view and specifics on the multi-file problem, see this.

So, you need to move your implementation of the split2 function to your header file. I know this will be ugly, but it's the only way to make it work well. You'll notice that many projects that use temlate classes and functions make use of a .hpp extension for header files with template implementations. This gives an indication that the header will contain both function declarations and definitions.

Aha, that was why. Thank you very much

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.