When I compile this:
Everything works just fine. However, if I compile the class seperately:Code:#include <iostream> #include <ctime> #include <cstring> #include <string> #include <fstream> #include <sstream> #define LGROPENFAIL 1 #define LGRWRITEFAIL 2 class logger { public: std::ofstream log; logger(std::string fpath, std::string who, bool fatal, bool buffd); template<typename T> logger& operator<< (const T &data); void stamp(); ~logger(); private: std::string id; bool fatal; bool buffd; }; logger::logger(std::string fpath, std::string who, bool fatal, bool buffd) { log.open(fpath.c_str(), std::ios::app|std::ios::out); this->fatal = fatal; this->buffd = buffd; if (log.rdstate() && fatal) throw LGROPENFAIL; id = who; stamp(); log << "LOGGER BEGIN.\n"; if (!buffd) log.flush(); } template<typename T> logger& logger::operator<< (const T &data) { std::stringstream oss; oss << data; log << oss.str(); if (!buffd) log.flush(); if (log.rdstate() && fatal) throw LGRWRITEFAIL; return *this; } void logger::stamp() { const time_t t = time(NULL); char *ts = ctime(&t), *p = strrchr(ts,' '); *(++p) = '\0'; log << ts << id << ": "; if (log.rdstate() && fatal) throw LGRWRITEFAIL; } logger::~logger() { stamp(); log << "LOGGER DONE.\n"; log.close(); } using namespace std; int main() { logger log("test.log", "tester", true, true); log.stamp(); log << "hey" << 23 << "\n"; return 0; }
logger.h
logger.cppCode:#include <ctime> #include <cstring> #include <string> #include <fstream> #include <sstream> #ifndef LGROPENFAIL #define LGROPENFAIL 1 #define LGRWRITEFAIL 2 #endif class logger { public: std::ofstream log; logger(std::string fpath, std::string who, bool fatal, bool buffd); template<typename T> logger& operator<< (const T &data); void stamp(); ~logger(); private: std::string id; bool fatal; bool buffd; };
Compile:Code:#include <logger.h> logger::logger(std::string fpath, std::string who, bool fatal, bool buffd) { log.open(fpath.c_str(), std::ios::app|std::ios::out); this->fatal = fatal; this->buffd = buffd; if (log.rdstate() && fatal) throw LGROPENFAIL; id = who; stamp(); log << "LOGGER BEGIN.\n"; if (!buffd) log.flush(); } template<typename T> logger& logger::operator<< (const T &data) { std::stringstream oss; oss << data; log << oss.str(); if (!buffd) log.flush(); if (log.rdstate() && fatal) throw LGRWRITEFAIL; return *this; } void logger::stamp() { const time_t t = time(NULL); char *ts = ctime(&t), *p = strrchr(ts,' '); *(++p) = '\0'; log << ts << id << ": "; if (log.rdstate() && fatal) throw LGRWRITEFAIL; } logger::~logger() { stamp(); log << "LOGGER DONE.\n"; log.close(); }
g++ -c -o logger.o logger.cpp
ar rcs liblogger++.a logger.o
Then use this:
logger-demo.cpp
and compile:Code:#include <logger.h> using namespace std; int main() { logger log("test.log", "tester", true, true); log.stamp(); log << "hey" << 23 << "\n"; return 0; }
gcc logger-demo.cpp -llogger++
I suddenly get:
/tmp/ccDZcs1z.o: In function `main':
logger-demo.cpp.text+0x24b): undefined reference to `logger& logger:
perator<< <char [4]>(char const (&) [4])'
logger-demo.cpp.text+0x257): undefined reference to `logger& logger:
perator<< <int>(int const&)'
logger-demo.cpp.text+0x264): undefined reference to `logger& logger:
perator<< <char [2]>(char const (&) [2])'
collect2: ld returned 1 exit status
So this is all specifically to do with the one template func overloading <<. I've never had a problem creating a static lib in C before, and I can't find any distinct caveats regarding doing it in C++. Anyone know what the deal is? I'm hoping it's just a switch I can add..



LinkBack URL
About LinkBacks
.text+0x24b): undefined reference to `logger& logger:
perator<< <char [4]>(char const (&) [4])'


