Ошибки компоновщика при использовании статических членов шаблона функции класса

Я не понимаю, почему он не компилируется правильно, компоновщик сообщает об отсутствующих символах:

Неопределенные символы для архитектуры 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) в Inventory.cpp.o

Потому что раньше в процессе я тоже вижу эту ошибку: /usr/bin/ranlib: file: liblibswinadventure.a(Utils.cpp.o) has no symbols Я предполагаю, что по какой-то причине он неправильно компилирует файл утилит.

Для справки, я использую CMake в системе Mac OS X 10.7 с большинством домашних инструментов, установленных и связанных.

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

Решение

Переместите определения функций вашего шаблона в заголовок.

Линкер говорит вам, что во время компиляции Inventory.cppособый экземпляр Utils::is_last было необходимо, но определение не было доступно для его создания.

И во время компиляции Utils.cppопределение Utils::is_last был доступен, но это создание не было необходимости.

Так что ни один исходный файл не смог создать эту функцию во время компиляции.

1

Другие решения

Когда вы объявляете шаблон, переменные внутри <> становятся заменой для переданного типа, и, как таковые, эти переменные используются так же, как классы, и их нужно объявлять только один раз. таким образом template <typename Iter, typename Cont> может рассматриваться как определение класса и перемещаться за пределы class Utils { определение. Другие случаи template должны быть удалены, особенно до Utils::func() определения. В нынешнем виде вы в основном говорите: «Создайте класс с именем Iter. Создайте класс с именем Iter. Создайте класс с именем Iter и т. Д.» Как только он встречает переменную типа «Iter», он не знает, какую из них использовать. Этот сайт должен помочь с шаблонами, и стоит посмотреть:

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

1

По вопросам рекламы [email protected]