Я получаю сообщение об ошибке связывания (LINK 2019) при попытке дополнить класс шаблоном - PullRequest
0 голосов
/ 08 мая 2020

Я пытаюсь построить простую структуру данных кучи для практики. Когда я собираю версию для double, она работает нормально.

class heapt {
public:
    heapt();
    heapt(std::initializer_list<double> lst);
    void print_heapt();
private:
    int size;
    int length;
    double* elem; //points to root
};

Его конструкторы работают отлично, и куча печатается должным образом. Но когда я пытаюсь обобщить его с помощью

template< typename Elem>

как:

template<typename Elem>
class heapt {
public:
    heapt();
    heapt(std::initializer_list<Elem> lst);
    void print_heapt();
private:
    int size;
    int length;
    Elem* elem; //points to root
};

для определения класса и как:

template<typename Elem>
heapt<Elem>::heapt(std::initializer_list<Elem> lst) :
size{ static_cast<int>(lst.size()) }, 
elem{new Elem[lst.size()]} 
{
    std::copy(lst.begin(), lst.end(), elem);//Now heaptify elem
    build_heapt(elem, lst.size());
}

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

Я получаю две ошибки связывания:

LNK2019 неразрешенный внешний символ «publi c: void __thiscall heapt :: print_heapt (void) "(? print_heapt @? $heapt@H@@QAEXXZ), на который ссылается функция _main

LNK2019 неразрешенный внешний символ" publi c: __thiscall heapt :: heapt (class std :: initializer_list) "(?? 0? $heapt@H@@QAE@V? $initializer_list@H@std@@@Z), на которое ссылается функция _main

Основная функция:

{
    heapt<int> hh{ 27,12,3,13,2,4,14,5 };

    std::cout << "Hello" << '\n';

    hh.print_heapt();
}

EDIT: The * Класс 1036 * находится в файле «heap.h», а определение конструктора heapt<Elem>::heapt(std::initializer_list<Elem> lst) находится в классе «heap. cpp», который имеет #include"heap.h" в качестве файла заголовка. Функция int main находится в файле с именем «InSo. cpp», который также имеет #include"heap.h" в качестве файла заголовка.

1 Ответ

0 голосов
/ 08 мая 2020

В объявлении вашего шаблонного класса вы используете heapt(std::initializer_list<double> lst);, но в своем определении вы используете std::initializer_list<Elem>. Вы должны изменить объявление на heapt(std::initializer_list<Elem> lst);

У вас все еще отсутствуют определения для print_heapt и build_heapt, но в противном случае он должен компилироваться.

EDIT: в свете того, что вы поясняете, как настроены ваши исходные файлы см. комментарий WhozCraig к вашему первоначальному сообщению. Вы можете либо включить определение шаблонных функций класса, например, в файл heap.hpp и включить его в конец вашего heap.h, либо просто собрать их все вместе в один файл, например

// heap.h
#ifndef HEAP_H
#define HEAP_H

#include <initializer_list>

template<typename Elem>
class heapt {
public:
    heapt();
    heapt(std::initializer_list<Elem> lst);
    void print_heapt();
private:
    int size;
    int length;
    Elem* elem; //points to root
};

#include "heap.hpp"

#endif

//heap.hpp
#ifndef HEAP_HPP
#define HEAP_HPP

#include "heap.h"
#include <algorithm>

template<typename Elem>
heapt<Elem>::heapt(std::initializer_list<Elem> lst) :
    size{ static_cast<int>(lst.size()) },
    elem{ new Elem[lst.size()] }
{
    std::copy(lst.begin(), lst.end(), elem);//Now heaptify elem
    //build_heapt(elem, lst.size());
}

#endif
...