1

I have been playing around with Template functions, and made a little logger program. I have been trying to split this into header / source file, but I keep getting linker errors. I know this is simple, but I cant figure it out.

Also I have some convince vars in the logger header, where would be the "proper" place for those? (logStart, logEnd etc.)

All code below.

Header

#ifndef __moot_logger_hpp__
#define __moot_logger_hpp__


#include <iostream>
#include <fstream>
#include <string>

using std::ios;

namespace Moot
{
    struct Logger
    {
        Logger();
        ~Logger() {}


        template <class T>      
        void saveToFile(T type);

        template <typename T>
        Logger& operator<< (T type);


        /*
        Logger& operator<< (std::wstring wideStr)
        {
            saveToFile(Moot::convertWstringToString(wideStr));
            return *this;
        }
        */
    };


    /*
    namespace {
        Logger logStart;
        Logger& lStart = logStart;

        const char  logEnd = '\n';
        const char& lEnd   = logEnd;

        const char  logSpace = ' ';
        const char& lSpace   = logSpace;
    }
    */

}


#endif

Source

#include <Moot/logger.hpp>

Moot::Logger::Logger()
{
    std::ofstream logfile;
    logfile.open ("logfile.txt", ios::trunc);
    logfile << "LogFile - most recent at the bottom\n";
    logfile << "-----------------------------------\n \n";
    logfile.close();
}


template <typename T>
void Moot::Logger::saveToFile(T type)
{
    std::ofstream logfile;
    logfile.open ("logfile.txt", ios::in | ios::app);
    logfile << type;
    logfile.close();
}


template <typename T>
Moot::Logger& Moot::Logger::operator<< (T type) 
{
    saveToFile(type);
    return *this;
}


/*
Logger::Logger& operator<< (std::wstring wideStr)
{
    saveToFile(Moot::convertWstringToString(wideStr));
    return *this;
}
*/

main

#include <Moot/logger.hpp>
#include <iostream>

int main()
{
    std::cout << "hello" << std::endl;

    Moot::Logger() << 12;
    //Moot::lStart.saveToFile(23);
    //Moot::lStart.operator << 13;

    return 0;
};
  • 2
    Please note that identifiers that begin with underscores are reserved. – Alexandre C. Sep 09 '10 at 20:32
  • 2
    You shouldn't use a using directive in a header; doing so only ends in tears. As for the "convenience variables," if they are only used in a single source file, you should put them in that source file. If they are used in multiple source files, you should put them in the header file, perhaps in a 'detail' namespace. Personally, I'm not a fan of using a global instance for a logger; it's much cleaner to pass a pointer or reference (or smart pointer, if needed) to the logger to the components that do logging (some people disagree with that point of view, though). – James McNellis Sep 09 '10 at 20:39
  • @Alexandre: `` It's a wee bit more complicated than that. Reserved are all identifiers starting with an underscore followed by a capital letter, all identifiers in the global namespace starting with an underscore, and all identifiers having two consecutive underscores anywhere. `` Still, rather than remembering these rules, it might be easier to avoid leading underscores altogether (and, of course, more than one consecutive ones), so basically, I agree with you. (`+1` from me.) – sbi Sep 09 '10 at 20:45
  • re the using directive James brought up (`+1` from me): http://stackoverflow.com/questions/2879555/c-stl-how-to-write-wrappers-for-cout-cerr-cin-and-endl/2880136#2880136 – sbi Sep 09 '10 at 20:49

2 Answers2

4

You'll want to read the C++ FAQ Lite question, "Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?"

Effectively, you need to define your function and class templates in the header file, not in the .cpp file.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
0

If you want divide definition from declaration for template classes than move definition to separate file with hpp or tpp (tpp not always correctly handled by text editors) extension and add include directive for definition file at the end of declaration file