我不明白为什么它没有正确编译,链接器会报告丢失的符号:
架构x86_64的未定义符号: “bool swinadventure :: Utils :: is_last< __ gnu_cxx :: __ normal_iterator>&gt ;,std :: vector>>(__ gnu_cxx :: __ normal_iterator>>,std :: vector> const&)”,引用自: swinadventure :: Inventory.cpp.o中的Inventory :: get_item_list(std :: string,std :: string)
因为在过程中我也看到了这个错误:/usr/bin/ranlib: file: liblibswinadventure.a(Utils.cpp.o) has no symbols
我认为它没有正确编译utils文件。
作为参考,我在Mac OS X 10.7系统上使用CMake,并安装和链接了大多数自制软件工具。
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 */
答案 0 :(得分:1)
将模板函数定义移至标题。
链接器告诉您,在编译Inventory.cpp
时,需要Utils::is_last
的特殊实例化,但是无法创建它的定义。
在编译Utils.cpp
时,Utils::is_last
的定义可用,但不需要实例化。
因此,两个源文件都无法在编译时创建该函数。
答案 1 :(得分:1)
当您声明模板时,&lt;&gt;内的变量成为传递类型的替身,因此这些变量的使用方式与类相同,只需要声明一次。因此,template <typename Iter, typename Cont>
可以被视为类定义,并移出class Utils {
定义之外。还应删除template
的其他实例,尤其是在Utils::func()
定义之前。就像现在一样,你基本上是在告诉它“创建一个名为Iter的类。创建一个名为Iter的类。创建一个名为Iter的类,等等”一旦遇到“Iter”类型的变量,它就不知道它应该使用哪一个。这个网站应该有助于模板,值得一看: