"Undefined reference to nazwa_funkcji", mimo iż wszystko jest dobrze.

0

Witam.

Kompilacja projektu przebiega pomyślnie, prawie.. Jedynie linker wypluwa:

D:\AppData\Tmp\cclfRANf.o:main.cpp:(.text+0x86): undefined reference to void ErrHandler<char*>(char*, char const*, char const*, bool, bool, void (*)())' >D:\AppData\Tmp\cclfRANf.o:main.cpp:(.text+0x180): undefined reference to void ErrHandler<char*>(char*, char const*, char const*, bool, bool, void ()())' >D:\AppData\Tmp\cclfRANf.o:main.cpp:(.text+0x2ff): undefined reference to void ErrHandler<bool>(bool, char const*, char const*, bool, bool, void (*)())' >D:\AppData\Tmp\cclfRANf.o:main.cpp:(.text.startup+0x7a): undefined reference to void ErrHandler<bool>(bool, char const, char const*, bool, bool, void ()())' ?>D:\AppData\Tmp\ccDhbo6y.o:AccountSystem.cpp:(.text+0xc5): undefined reference to void ErrHandler<char*>(char*, char const*, char const*, bool, bool, void (*)())' ?>D:\AppData\Tmp\ccDhbo6y.o:AccountSystem.cpp:(.text+0x207): undefined reference to void ErrHandler<bool>(bool, char const, char const*, bool, bool, void (*)())' >collect2.exe

Tak wyglądają pliki (kolejno) ErrorHandler.h i ErrorHandler.cpp:

#ifndef ERROR_HANDLER_H
#define ERROR_HANDLER_H

#include <iomanip>
#include <iostream>
#include <cstring>
#include <windows.h>

void nullfunc();

enum color {C_ERROR = 12, C_FATAL_ERROR = 4, C_NORMAL = 7};
void setcolor(color c);

template <typename ErrCode>
void ErrHandler(ErrCode code, const char* function,
                const char* msg, bool IsFatal,
                bool OtherAction = false, void(*func)() = nullfunc);

#endif

#include "ErrorHandler.h"

void nullfunc(){
    std::cerr<<"Fatal error! Null function called. Terminating program..";
    exit(0);
}

void setcolor(color c){
    static HANDLE HOut = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(HOut, c);
}

template <typename ErrCode>
void ErrHandler(ErrCode code,
                const char* function,
                const char* msg,
                bool IsFatal,
                bool OtherAction,
                void(*func)()){
    if(!code){
        if(IsFatal){
            setcolor(C_FATAL_ERROR);
            std::cerr<<"\nFatal error! ";
        }else {
            setcolor(C_ERROR);
            std::cerr<<"\nError! ";
        }
        std::cerr<<"In function ["<<function<<"]: \""<<msg<<"\"\n";
        setcolor(C_NORMAL);
        if(OtherAction){
            std::cout<<" Calling error function... \n###########################\n";
            func();
        }
        if(IsFatal) exit(0);
    }
    return;
}

Sprawdzałem kilka razy definicję i deklarację, wszystko jest tak samo. Wywołania również są poprawne.
Kompiluję w taki sposób: "g++ -Wall -Wextra -pedantic-errors -O3 -Os -I. -std=c++1z main.cpp AccountSystem\AccountSystem.cpp ErrorHandler\ErrorHandler.cpp HalfCipher.cpp";

Za wszelką pomoc byłbym wdzięczny.

Pozdrawiam.

3

Definicja szablonu musi znajdować się w nagłówku¹.

Alternatywnie (nie polecam tego rozwiązania w domyślnym przypadku), możesz wymusić konkretyzację dla wybranych typów wewnątrz pliku .cpp

¹ to jest lekkie uproszczenie, ale zostańmy przy tym.

0

przecież jest:

template <typename ErrCode> <<--
void ErrHandler(ErrCode code, const char* function,
                const char* msg, bool IsFatal,
                bool OtherAction = false, void(*func)() = nullfunc);

chyba, że "nagłówek" to coś innego.

1

To jest deklaracja szablonu funkcji, nie jego definicja. Definicje (ciało funkcji) masz w pliku .cpp.

1 użytkowników online, w tym zalogowanych: 0, gości: 1