function specialzation in a template class

D

Dick Swager

I have a template class in C++/CLI that looks like this:


template <typename Hdr, typename T>
class DataFile : public DataFileBase
{
protected:
Hdr* header;
Signal <T>* signal;
string fileName;

public:
DataFile ()
: header (0), signal (0), fileName ("") {};

...
// Specialize the ReadSignal function for HP EU Data.
template <>
void ReadSignal <HPDataHeader, float> (ifstream* dataFile)
{
...
}

...
};

This is all defined and implemented in a *.h file and it works fine.

Now I need to use this template class somewhere else that has no need for
the

specialized function but I still have to add a using statement for
HPDataHeader (which

is in a pure native C++ library) because of the specialized type. In other
words, I'm

carrying garbage along when I include the header. So I want to move the
function

specialization out of the *.h file and into a *.cpp file. The code in the
*.cpp file

that I use is like this:

// Specialize the ReadSignal function for HP EU Data.
template <typename Hdr, typename T>
void DataFile <HPDataHeader, float>::ReadSignal (ifstream* dataFile)
{
...
}

This results in a compilation error:

error C2244: 'UERDDataFile::DataFile<Hdr,T>::ReadSignal' : unable to match
function

definition to an existing declaration

and the output is this:

1>------ Build started: Project: DataFile, Configuration: Debug Win32 ------
1>Compiling...
1>DataFile.cpp
1>.\DataFile.cpp(75) : error C2244:
'UERDDataFile::DataFile<Hdr,T>::ReadSignal' :

unable to match function definition to an existing declaration
1> with
1> [
1> Hdr=double,
1> T=float
1> ]
1> definition
1> 'void UERDDataFile::DataFile<Hdr,T>::ReadSignal(std::ifstream *)'
1> with
1> [
1> Hdr=double,
1> T=float
1> ]
1> existing declarations
1> 'void UERDDataFile::DataFile<Hdr,T>::ReadSignal(std::ifstream *)'
1> with
1> [
1> Hdr=double,
1> T=float
1> ]
1>Build log was saved at
"file://c:\UERD\URoot\DataFile\DataFile\Debug\BuildLog.htm"
1>DataFile - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

It looks to me like the 'definition' is exactly the same as the 'existing

declarations'! What am I doing wrong????

I also tried:

// Specialize the ReadSignal function for HP EU Data.
template <>
void DataFile <HPDataHeader, float>::ReadSignal (ifstream* dataFile)
{
...
}

which is more in line with examples that I found but that resulted in a slew
of

compilation errors as well as the C2244 error.

TIA, Dick
 
B

Ben Voigt [C++ MVP]

Dick said:
I have a template class in C++/CLI that looks like this:


template <typename Hdr, typename T>
class DataFile : public DataFileBase
{
protected:
Hdr* header;
Signal <T>* signal;
string fileName;

public:
DataFile ()
: header (0), signal (0), fileName ("") {};

...
// Specialize the ReadSignal function for HP EU Data.
template <>
void ReadSignal <HPDataHeader, float> (ifstream* dataFile)

Do you mean for these types to specialize the containing class? They don't.
{
...
}

...
};


Maybe what you want is more like:

template <typename Hdr, typename T, typename CompileTimeOverrides =
DataFile<Hdr,T> >
class DataFile : public DataFileBase
{
protected:
Hdr* header;
Signal <T>* signal;
string fileName;

public:
DataFile ()
: header (0), signal (0), fileName ("") {};

void ReadSignal( ifstream* dataFile ) {
static_cast<CompileTimeOverrides*>(this)->ReadSignalImpl(); }

void ReadSignalImpl(ifstream* dataFile) { ... }
};

/* in the file defining HPDataHeader */
struct HPDataHeader { ... };

class HpEuDataFile : public DataFile<HPDataHeader, float, HpEuDataFile>
{
protected:
/* re-implement constructors, yuck! */
public:
void ReadSignalImpl(ifstream* dataFile) { ... }
};

template<>
class DataFile<HPDataHeader, float> : public HpEuDataFile
{
/* re-implement constructors, yuck! */
};

As a result of the need to re-implement constructors, you may want to apply
PImpl, move most of the constructor logic to a protected helper, or some
other mechanism.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top