0

正しくコンパイルされない理由がわかりません。リンカはシンボルの欠落を報告します。

アーキテクチャ x86_64 の未定義シンボル: "bool swinadventure::Utils::is_last<__gnu_cxx::__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 */
4

2 に答える 2

1

テンプレート関数定義をヘッダーに移動します。

リンカは、コンパイルInventory.cpp中にの特別なインスタンス化Utils::is_lastが必要であると言っていますが、それを作成するための定義は利用できませんでした。

そして、コンパイル中Utils.cppに、の定義Utils::is_lastが利用可能でしたが、そのインスタンス化は必要ありませんでした。

したがって、どちらのソースファイルもコンパイル中にその関数を作成できませんでした。

于 2012-09-15T16:04:09.297 に答える
1

テンプレートを宣言すると、 <> 内の変数は渡された型の代役になるため、これらの変数はクラスと同じように使用され、一度だけ宣言する必要があります。したがってtemplate <typename Iter, typename Cont>、クラス定義であるかのように扱い、class Utils {定義の外に移動する必要があります。の他のインスタンスtemplateも、特にUtils::func()定義の前に削除する必要があります。現状では、基本的に「Iter という名前のクラスを作成する。Iter という名前のクラスを作成する。Iter という名前のクラスを作成する、など」と指示していることになります。タイプ「Iter」の変数に遭遇するとすぐに、どれを使用すべきかわかりません。このサイトはテンプレートに役立つはずであり、一見の価値があります:

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

于 2012-09-15T16:17:02.723 に答える