From: Andrew Falanga on
Hi,

I looked on the C++ FAQ-Lite and found a solution, but my method of
implementation isn't quite right. The link I went off of is
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.7.

Now, I have in my header file:

#include <iostream>
#include <fstream>
#include <sstream>

enum logMode { stdoutonly, fileonly, both };
enum directive { flush };

class Log {
std::fstream logFile;
std::string logFileName;

logMode currMode;

public:
// c-tors here, and d-tor

template <typename T>
Log& operator << ( T );
};

template <typename T>
Log& Log::operator << ( T t ) {
std::ostringstream os;

os << t;

// write os to log file and stdout, if applicable
return *this;
}

template <> Log& Log::operator << <logMode> ( logMode m ) {
// set the log mode
return *this;
}

template <> Log& Log::operator << <directive> ( directive d ) {
// do something important with the directive
return *this;
}

Now, all of my modules compiled ok but when I start linking things
together to get binaries, I was getting compiler errors like this one
(from VC):

Common.o : error LNK2005: "public: class Log & __thiscall
Log::operator<<<enum l
ogDirectives>(enum logDirectives)" (??$?
6W4logDirectives@@@Log@@QAEAAV0(a)W4logDir
ectives@@@Z) already defined in Logging.o

I made this change because originally, my Log class had this for
definitions for the overloaded << operator:

template <typename T>
Log& operator << ( T t );

Log& operator << ( logModes l );
Log& operator << (directives d );

I figured that the template would be used when the passed in argument
wasn't "logModes" or "directives." But this was apparently incorrect
because looking through the output from some of my threads these enums
were being logged not handled correctly.

How do I resolve this issue?

Andy
From: Josh Sebastian on
Andrew Falanga wrote:

> Hi,
>
> I looked on the C++ FAQ-Lite and found a solution, but my method of
> implementation isn't quite right. The link I went off of is
> http://www.parashift.com/c++-faq-lite/templates.html#faq-35.7.

[ snip example with template member function ]

> Common.o : error LNK2005: "public: class Log & __thiscall
> Log::operator<<<enum l
> ogDirectives>(enum logDirectives)" (??$?
> 6W4logDirectives@@@Log@@QAEAAV0(a)W4logDir
> ectives@@@Z) already defined in Logging.o

It worked fine for me with GCC (once I added a ctor and a driver). What
version of VC are you using?

--
Josh
From: Andrew Falanga on
On Jan 17, 5:25 am, Josh Sebastian <sebas...(a)gmail.com> wrote:
> Andrew Falanga wrote:
> > Hi,
>
> > I looked on the C++ FAQ-Lite and found a solution, but my method of
> > implementation isn't quite right. The link I went off of is
> >http://www.parashift.com/c++-faq-lite/templates.html#faq-35.7.
>
> [ snip example with template member function ]
>
> > Common.o : error LNK2005: "public: class Log & __thiscall
> > Log::operator<<<enum l
> > ogDirectives>(enum logDirectives)" (??$?
> > 6W4logDirectives@@@Log@@QAEAAV0(a)W4logDir
> > ectives@@@Z) already defined in Logging.o
>
> It worked fine for me with GCC (once I added a ctor and a driver). What
> version of VC are you using?
>
> --
> Josh

I'm not actually using VC for my development (it's too cumbersome),
however, the version of the compiler I'm using is:

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762
for 80x86

Andy