«Неопределенная ссылка на class :: function ...» - неправильно ли я ссылаюсь? - PullRequest
1 голос
/ 07 марта 2011

Я работаю над этим классом NeuralNet:

class NeuralNet {
public:
    // Public functions
private:
    vectors vect; // Point-of-access for functions in class vectors
    // Private functions
};

И я использую этот чрезвычайно простой make-файл:

all: nnet.exe
nnet.exe: main.o neuralnet.o vectors.o
    g++ -o nnet.exe main.o vectors.o neuralnet.o
main.o: main.cpp neuralnet.h
    g++ -ggdb -c main.cpp
vectors.o: vectors.cpp vectors.h
    g++ -ggdb -c vectors.cpp
neuralnet.o: neuralnet.cpp neuralnet.h vectors.h
    g++ -ggdb -c neuralnet.cpp
clean:
    rm -f *.o nnet.exe

Когда g ++ запускается для создания окончательного исполняемого файла,Я получаю много ошибок в следующей форме:

neuralnet.o: /path/to/neuralnet.cpp: line# : undefined reference to vectors::fn_name(args)

Например, я определил функцию:

template<typename T> void fill_vec(vector<T>&, int, double);

Когда я вызываю эту функцию, я передаю переменную, объявленную с типом vector<double> для первого аргумента, и компоновщик сообщает undefined reference to void vectors::fill_vec<double>(std::vector<double, std::allocator<double> >&, int, double)

Все вызовы функций class vectors в реализации NeuralNetот vect.Тем не менее, neuralnet.cpp и neuralnet.h содержат включения для "vectors.h" , поэтому я предполагаю, что я каким-то образом неправильно связываю ссылки.

Кто-нибудь видит что-нибудь очевидное?

1 Ответ

2 голосов
/ 07 марта 2011

Если вы не определили fn_name() в строке в vectors.h , просто включив этот заголовок из neuralnet.cpp и neuralnet.h недостаточно.Убедитесь, что вы действительно можете указать пальцем на это функциональное тело.Вы, вероятно, намеревались сделать это в vectors.cpp .

Быть шаблоном меняет все.Вы должны определить методы шаблона в файле заголовка, а не в файле .cpp.Хотя вы можете определить fill_vec<T> в вашем исходном файле, компилятор на самом деле не создает его для каких-либо значений T, потому что внутри этого модуля перевода он не нуждается ни в каких экземплярах.Вы можете вручную создать его экземпляр для каждого значения T, которое вам понадобится, но проще просто определить функцию в заголовке в том же месте, где вы ее объявили.Таким образом, у компилятора есть определение, доступное везде, где это необходимо.Вы получите несколько экземпляров (по одному на каждую единицу перевода, которая их использует), но компоновщик знает, как их объединить.

См. Также Неопределенная ошибка ссылки для метода шаблона .

...