Ошибка компоновщика для нетипичного параметра шаблона

все.

Я сделал набор кодов c ++ следующим образом.
Затем я собрал каждый .cpp в .o g ++, успешно.
Тем не менее, я получил ошибку связи как

 Undefined symbols for architecture x86_64:
"derive1<3>::derive1(int)", referenced from:
derive2::derive2(int)in derive2.o
derive2::derive2(int)in derive2.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

Не могли бы вы сказать мне, что происходит? Если я связываю все фрагменты кода в одном файле, я не получаю никаких ошибок, и все работает отлично, как я и предполагал. Я предполагаю, что я должен ввести ключевое слово extern где-то, но я не знаю, как это сделать.

Мой компилятор

i686-apple-darwin11-llvm-g ++ — 4.2 (GCC) 4.2.1 (на основе Apple Inc.
сборка 5658) (сборка LLVM 2336.11.00)

«Base.hpp»

class base {
public:
virtual int hoge( int num ) = 0;

};

«Derive1.hpp»

#include "base.hpp"#include <iostream>

template <int N>
class derive1 : public base {
public:
explicit derive1( int n );
virtual int hoge( int num ) {
std::cout << "num = " << num << std::endl
<< "N = " << N << std::endl;
return N;
}

};

«Derive1.cpp»

#include "derive1.hpp"
template <int N>
derive1<N>::derive1 ( int n ) {
std::cout << "This is the constructer of derive1" << std::endl
<< "N = " << N << ", n = " << n << std::endl;
}

«Derive2.hpp»

#include "derive1.hpp"#include <iostream>

class derive2 : public derive1<3> {
public:
explicit derive2( int n );
};

«Derive2.cpp»

#include "derive2.hpp"
derive2::derive2( int n ) : derive1<3>( n ) {
std::cout << "This is the constructer of derive2" << std::endl
<< "n = " << n << std::endl;
}

«Derive_test.cpp»

#include<iostream>
#include "derive2.hpp"
int main() {

derive2 test(3);

std::cout << "return value = "<< test.hoge( 5 )
<< std::endl;
return 0;
}

-1

Решение

Не следует разбивать определение и реализацию для файлов .h и .cpp для шаблонных классов.

Что такое неопределенная ссылка / неразрешенная внешняя ошибка символа и как ее исправить?

1

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

К сожалению, большинство компиляторов требуют, чтобы реализация функции шаблона (в этом случае template <int N> derive1<N>::derive1 ( int n ) доступен для модуля компиляции, использующего его. Переместите его в «производное 1.hpp».

1

Ответ прост: вы должны поместить весь шаблонный код (derive1::derive1(int) и т.д.) в заголовочные файлы, а не в собственные единицы перевода. Компилятор должен видеть полное определение, когда он пытается создать экземпляр шаблона. Конечно ты Можно иметь определение шаблона в *.cpp файл, но затем вы должны явно указать его, а также объявить эту специализацию в заголовочном файле.

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