0

I don't understand why it's not compiling correctly, the linker reports missing symbols:

Undefined symbols for architecture x86_64: "bool swinadventure::Utils::is_last<__gnu_cxx::__normal_iterator > >, std::vector > >(__gnu_cxx::__normal_iterator > >, std::vector > const&)", referenced from: swinadventure::Inventory::get_item_list(std::string, std::string) in Inventory.cpp.o

Because eariler in the process I also see this error: /usr/bin/ranlib: file: liblibswinadventure.a(Utils.cpp.o) has no symbols I assume that it's not compiling the utils file correctly for some reason.

For reference, I'm using CMake on a Mac OS X 10.7 system with most homebrew tools installed and linked.

Utils.h

#ifndef UTILS_H_ #define UTILS_H_ #include <vector> namespace swinadventure { /** * Static class for various utilities and helper functions */ class Utils { public: template <typename Iter> static Iter next_iterator(Iter iter); template <typename Iter, typename Cont> static bool is_last(Iter iter, const Cont& cont); }; } /* namespace swinadventure */ #endif /* UTILS_H_ */ 

Utils.cpp

#include "Utils.h" namespace swinadventure { /** * Returns the next iterator * http://stackoverflow.com/questions/3516196/testing-whether-an-iterator-points-to-the-last-item * @param iter * @return */ template <typename Iter> Iter Utils::next_iterator(Iter iter) { return ++iter; } /** * Checks if the iterator is the last of the vector array * http://stackoverflow.com/questions/3516196/testing-whether-an-iterator-points-to-the-last-item * @param iter iterator * @param cont vector array * @return */ template <typename Iter, typename Cont> bool Utils::is_last(Iter iter, const Cont& cont) { return (iter != cont.end()) && (next_iterator(iter) == cont.end()); } } /* namespace swinadventure */ 
3

2 Answers 2

1

Move your template function definitions to the header.

The linker is telling you that while compiling Inventory.cpp, a special instantiation of Utils::is_last was needed, but the definition wasn't available to create it.

And while compiling Utils.cpp, the definition of Utils::is_last was available, but that instantiation wasn't needed.

So neither source file was able to create that function while compiling.

Sign up to request clarification or add additional context in comments.

Comments

1

When you declare a template, the variables inside the <> become stand-ins for the type passed, and as such these variables are used in the same way as classes and only need to be declared once. Thus template <typename Iter, typename Cont> can should be treated as if it were a class definition, and moved outside of the class Utils { definition. The other instances of template should be removed as well, especially before the Utils::func() definitions. As it stands now, you're basically telling it "Create a class named Iter. Create a class named Iter. Create a class named Iter, etc." As soon as it encounters a variable of the type 'Iter', it doesn't know which one it should use. This site should help with templates, and is worth the look:

http://www.parashift.com/c++-faq/templates.html

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.