Archived

This topic is now archived and is closed to further replies.

moucard

Weird compiler error in VC++ 6.0

Recommended Posts

Another hour, another post... anyway here it goes: I''m having to seperate classes in my application,one is CBall, the other CTrace. In CBall I have 2 private methods which use templates:
template
std::ostream& CBall::WriteBinData(std::ostream& os, const T& data)
{
  os.write((const char*)&data, sizeof(T));
  return os;
}

template
std::istream& CTrace::ReadBinData(std::istream& is, T& data)
{
  is.read((char*)&data, sizeof(T));
  return is;
}
 
for writing into a binary file. I''ve worked a lot with these methods so far without having any problems. Now I''m trying to add these methods to the CTrace class the same way (private) to use them there as well. (I know this is probably bad and that I should create another .cpp file to use the methods). When I''m trying to compile the CTrace class VC++ tells me that: error C2893: Failed to specialize function template ''class std::basic_ostream > &__thiscall CTrace: :WriteBinData(class std::basic_ostream > &,const T &)'' With the following template arguments: ''const unsigned char *'' pointing me to the line that uses the function. What''s wrong here? why does it work for one class and not for another?

Share this post


Link to post
Share on other sites
It was only a typo but here it goes

template
std::ostream& CTrace::WriteBinData(std::ostream& os, const T& data)
{
os.write((const char*)&data, sizeof(T));
return os;
}

Share this post


Link to post
Share on other sites
All I can say is that MSVC 6 is more finicky than a cat when it comes to template code. It could be perfectly valid code that would compile fine on a different compiler, but I think I would need to see a more complete class definition to be sure.

Share this post


Link to post
Share on other sites
Ok here is my class listing:

// the header

#ifndef _CTRACE_H
#define _CTRACE_H

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
#include <sstream>
#include <fstream>
#include <cstdio>

using namespace std;

//define the codes for the events

// EC = Event Code

const unsigned char gc_ucEC_MouseMove = 0; // the mouse was moved

const unsigned char gc_ucEC_MouseButton = 1; // the left mouse button was pressed or de-pressed

const unsigned char gc_ucEC_Attention = 2; // we used an item from the library to get the attention of the child

const unsigned char gc_ucEC_Reassurance = 3; // we used an item from the library to reassure the child.

const unsigned char gc_ucEC_Message = 4; // received a message from the control module.


// define the 2 codes for where to save the data

// WC = Write Code

#define WC_FILE 0x01 // write the data to a file

#define WC_NET 0x02 // send the data over the network.


class CTrace {
private:
unsigned char m_ucWriteCode;
ofstream traceFile;

template<class T> std::ostream& WriteBinData(std::ostream& os, const T& data);
template<class T> std::istream& ReadBinData(std::istream& is, T& data);
/* double m_dTimeStamp;
bool m_bButtonPress;
short int m_siMouseX;
short int m_siMouseY;
short int m_siElement;*/

public:
CTrace(string sChildsName_, unsigned char ucWriteCode_);
~CTrace();

// Button Press

void SaveData(/*unsigned char ucECCode_, */double dTimeStamp_, bool bButtonPress_);
// MouseMove

void SaveData(/*unsigned char ucECCode_, */double dTimeStamp_, short int siMouseX,
short int siMouseY);
void SaveAttentionData(double dTimeStamp_, short int siElement_);
void SaveReassuranceData(double dTimeStamp_, short int siReassurance_);
};

#endif

// and the methods from the cpp file

template<class T>
std::ostream& CTrace::WriteBinData(std::ostream& os, const T& data)
{
os.write((const char*)&data, sizeof(T));
return os;
}

template<class T>
std::istream& CTrace::ReadBinData(std::istream& is, T& data)
{
is.read((char*)&data, sizeof(T));
return is;
}

Right now I'm bypassing the functions (the project compiles fine if I don't use them) by using the write method directly but it makes my code a little bit harder to read. The weird thing is how come these methods compile and are used perfectly in another class in the same project and not in this class? Am I missing something in my C++ skills or is it MS that I should blame?

edit: template code doesn't play nicely with the [code] tag. The [source] tag should be used instead for situations like this

[edited by - SiCrane on May 19, 2004 5:16:26 AM]

Share this post


Link to post
Share on other sites
Does it work if you move the function definitions form the .cpp file to the header file? Seperate compilation of templates is not a happy thing.

Also, how are you calling the functions that would generate the error?

Share this post


Link to post
Share on other sites
Actually defining the functions in the header worked.
I''m calling the functions like this:

WriteBinData(traceFile, gc_ucEC_MouseButton); WriteBinData(traceFile, dTimeStamp_);
WriteBinData(traceFile, bButtonPress_);


where traceFile is an ofstream. Thank you for your help!
But what bugs me now is why the hell does it work with the definitions in the cpp file in 2 other classes in the same project, (one declared public and the other private) and not in this one? Is it because having a public template method interferes somehow? The methods that I had the problem where declared as private as I wrote above. Thank you again!

Share this post


Link to post
Share on other sites
It was probably either because you were only using the template functions in translation units with proper template definition visibility or because you were inadvertently creating the template instantiations in translation units with proper visibility that exported the definitions so that outside translation units would function correctly.

edit: If you didn't understand that last sentence, don't worry about it. Basically it translates into: "just because". In the future, just stick the definitions in the header to begin with. Working with templates is enough of a mess that you don't need any additional things to worry about.

[edited by - SiCrane on May 19, 2004 5:50:25 AM]

Share this post


Link to post
Share on other sites