Вопрос по template-classes, c, undefined-reference, class, c++ – Шаблон класса C ++ неопределенная ссылка на функцию [дубликат]

7

На этот вопрос уже есть ответ здесь:

неопределенная ссылка на функцию шаблона [дубликат] 2 ответа

Я продолжаю получать неопределенную ссылку, когда я вызываю две функции из моего шаблона класса «добавить» и «больше» в моей основной функции.

Итак, у меня есть: number.h

#ifndef NUMBER_H
#define NUMBER_H

template <class T>
class number {
public:
    T x;
    T y;

    number (int a, int b){
        x=a; y=b;}
    int add (T&);
    T greater ();
};

#endif

number.cpp

#include "number.h"

template <class T>
int number<T>::add (T& rezAdd){
    rezAdd = x+y;
    return 1;
}

template <class T>
T number<T>::greater (){
        return x>y? x : y;
}

И мой основной файл: resolver.cpp

#include <stdio.h>
#include <stdlib.h>
#include "number.h"

int main (int argc, char **argv) {
    int aux;
    number<int> c(3,5);

    c.add(aux);
    printf ("number added [%d]\n", c.add(aux));
    printf ("greater number: [%d]\n", c.greater());

    return 0;
}

Ошибки, которые я продолжаю получать:

g++ -Wall -o tema1 resolver.cpp number.cpp
/tmp/ccX483J4.o: In function `main':
resolver.cpp:(.text+0x34): undefined reference to `number<int>::add(int&)'
resolver.cpp:(.text+0x47): undefined reference to `number<int>::add(int&)'
resolver.cpp:(.text+0x64): undefined reference to `number<int>::greater()'
collect2: ld returned 1 exit status
make: *** [all] Error 1

Спасибо за помощь в продвижении!

Ваш Ответ

3   ответа
5

cai где все ваши функции принадлежат классу с именемnumber: http://ideone.com/ZayX0c

Еще одна вещь ... вы не можете иметь шаблоны в .cpp файле. Шаблонные функции / определения идут в заголовке вместе с объявлением класса. Это причина вашей неопределенной ошибки функции. Не шаблонные функции идут в .cpp.

#include <cstdio>
#include <cstdlib>

template <class T>
class number {
public:
    T x;
    T y;

    number (int a, int b){
        x=a; y=b;}
    int add (T&);
    T greater ();
};

template <class T>
int number<T>::add (T& rezAdd){
    rezAdd = x+y;
    return 1;
}

template <class T>
T number<T>::greater (){
        return x>y? x : y;
}


int main (int argc, char **argv) {
    int aux;
    number<int> c(3,5);

    c.add(aux);
    printf ("number added [%d]\n", c.add(aux));
    printf ("greater number: [%d]\n", c.greater());

    return 0;
}
работает сейчас! большое спасибо за помощь MihaiGrad
я отредактировал это неправильно. Извини за это. MihaiGrad
кто-то сказал изменить "число <int> c (3,5);" в основной функции с "number <int> c = number <int> (3, 5);" но я продолжаю получать ошибки, упомянутые ранее MihaiGrad
Я отредактировал ответ. Поместите реализацию вашего шаблона в заголовок (.h). Не шаблонные реализации идут в теле (.cpp) Brandon
Нет разницы в этом конкретном случае. Все, что вам нужно сделать, это переместить все вашиtemplate функции к заголовку и все не шаблонные функции к файлу реализации. Brandon
3

add а такжеgreater шаблоны функций в вашnumber.h.

Помни чтоadd а такжеgreater нефункциионишаблоны функций, Для создания реальных функций компилятор должен создать экземпляр шаблона для определенных типов, таких какintи он может сделать это только в том случае, если у него есть доступ к определению шаблона в тот момент, когда он обнаруживает, что необходим экземпляр.

Когда вы компилируетеnumber.cppу компилятора есть доступ к определениям шаблонов, но он не видит код, который требует определенного экземпляра (например,number<int>), поэтому он не генерирует экземпляры.

Когда вы компилируетеresolver.cppкомпилятор видит, что ему нужно создать эти шаблоны дляint типа, но не может, так как не имеет их определения. Таким образом, он генерирует «внешние ссылки», в основном заметки, указывающие компоновщику искать эти функции в каком-то другом объектном файле.

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

Перемещение определений функций шаблона в заголовок делает их видимыми для компилятора во время его компиляцииmain.cppтак что он может создавать экземпляры этих функций дляint тип. Шаблоны функций обычно должны быть определены в заголовочных файлах, а не.cpp файлы, именно по этой причине.

очень полезно. Спасибо за помощь! MihaiGrad
4

.cpp файл, независимо от того, являются ли они шаблонными функциями или обычными функциями. И есть способ сделать это с некоторыми основными#ifndef магия. Вот что вы можете сделать:

main.cpp

#include "myclass.hpp"

int main()
{
  // ...
}

myclass.hpp

#ifndef MYCLASS
#define MYCLASS

template<class T>
class MyClass
{
  T val;
public:
  MyClass(T val_);
}

#define MYCLASS_FUNCTIONS
#include "myclass.cpp"

#endif

myclass.cpp

#ifndef MYCLASS_FUNCTIONS
#include "myclass.hpp"

// regular functions:
// ...

#else

// template functions:
template<class T>
MyClass<T>::MyClass(T val_)
    :val(val_)
{}

// ...
#endif

Вот как это видит прекомпилятор. У нас есть два.cpp файлы.

Когда мы компилируем main.cpp, мы:включаютmyclass.hppПроверь этоMYCLASS не определено, и этоопределить этодать компилятору определения сгенерированного класса (из класса шаблона)включаютmyclass.cppопределятьMYCLASS_FUNCTIONSпроверить, еслиMYCLASS_FUNCTIONS определяется, этодать компилятору определения сгенерированных функций (из шаблонных функций)Когда мы компилируем myclass.cppпроверить, еслиMYCLASS_FUNCTIONS определяется, это невключаютmyclass.hppПроверь этоMYCLASS не определено, и этоопределить этодать компилятору определения классавключаютmyclass.cppвключаютmyclass.hpp сноваэтот разMYCLASS определяется, так что ничего не делать внутри, вернуться кmyclass.cppпроверить, еслиMYCLASS_FUNCTIONS определяется, этодать компилятору определение сгенерированных функций (из шаблонных функций)выход включает в себя дваждыпередать компилятору все обычные функции
Лучшее описание решения. Я точно искал это и нашел его через месяц. («Лучше поздно, чем никогда»). Shravan40

Похожие вопросы