【问题标题】:Linker errors using static function template members of a class使用类的静态函数模板成员的链接器错误
【发布时间】:2012-09-15 15:57:06
【问题描述】:

我不明白为什么编译不正确,链接器报告缺少符号:

架构 x86_64 的未定义符号: “bool swinadventure::Utils::is_last<:__normal_iterator>>, std::vector > >(__gnu_cxx::__normal_iterator >>, std::vector > const&)”,引用自: swinadventure::Inventory::get_item_list(std::string, std::string) in Inventory.cpp.o

因为在这个过程的早期,我也看到了这个错误:/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 */

【问题讨论】:

标签: c++ templates vector compiler-errors cmake


【解决方案1】:

将模板函数定义移动到标题。

链接器告诉您,在编译 Inventory.cpp 时,需要 Utils::is_last 的特殊实例化,但无法创建它的定义。

在编译 Utils.cpp 时,Utils::is_last 的定义可用,但不需要实例化。

所以在编译时两个源文件都无法创建该函数。

【讨论】:

    【解决方案2】:

    当你声明一个模板时,里面的变量会成为传递的类型的替身,因此这些变量的使用方式与类相同,只需要声明一次。因此template &lt;typename Iter, typename Cont&gt; 应该被视为一个类定义,并移出class Utils { 定义。 template 的其他实例也应该被删除,尤其是在 Utils::func() 定义之前。就目前而言,您基本上是在告诉它“创建一个名为 Iter 的类。创建一个名为 Iter 的类。创建一个名为 Iter 的类,等等。”一旦遇到“Iter”类型的变量,它就不知道应该使用哪个变量。这个网站应该有助于模板,值得一看:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-15
      • 1970-01-01
      相关资源
      最近更新 更多