Hello everyone,

I am working on a project on Visual C++ 6.0 and I need to port some code
that uses partial specialization of class templates:

#include <cstddef>
#include <iostream>

// Extracts the type of an object.
template <class T>
struct extract { typedef T type; };

// Extracts the type of an array.
template <class T, std::size_t N>
struct extract<T[N]> { typedef T type; };

// Primary template for object new.
template <class T> struct TrackNewHelper
{
static T* TrackNew( T* ptr, const char* file, int line)
{
std::cout << "Tracking object allocation" << std::endl;
return ptr;
}
};

// Partial specialization for array new.
template <class T, std::size_t N> struct TrackNewHelper<T[N]>
{
static T* TrackNew( T* ptr, const char* file, int line)
{
std::cout << "Tracking array allocation " << std::endl;
return ptr;
}
};

// Forwards the call to helper classes.
template <class T> typename extract<T>::type* TrackNew(
typename extract<T>::type* ptr, const char* file, int line )
{
return TrackNewHelper<T>::TrackNew( ptr, file, line );
}

#define NEW( T ) TrackNew<T>( new T, __FILE__, __LINE__ )

int main()
{
int * p = NEW( int ); // Calls the primary template.
delete p;

p = NEW( int[64] ); // Calls the partial specialization.
delete [] p;

return 0;
}

I found a hint on the internet saying that class member templates can
simulate partial specialization, but unfortunately, no further information
was given. Does anyone happen to know a workaround for the code above?

--
Matthias Hofmann
Anvil-Soft, CEO
http://www.anvil-soft.com - The Creators of Toilet Tycoon
http://www.anvil-soft.de - Die Macher des Klomanagers

Re: VC++ 6.0 workaround for partial specialization by Ulrich

Ulrich
Thu Oct 25 07:30:55 PDT 2007

Matthias Hofmann wrote:
> I am working on a project on Visual C++ 6.0 and I need to port some code
> that uses partial specialization of class templates:

My spontaneous response to this is: Forget it and get an at least halfway
modern compiler!

Anyway, let's see...

> // Extracts the type of an object.
> template <class T>
> struct extract { typedef T type; };
>
> // Extracts the type of an array.
> template <class T, std::size_t N>
> struct extract<T[N]> { typedef T type; };
[...]
> // Forwards the call to helper classes.
> template <class T> typename extract<T>::type* TrackNew(
> typename extract<T>::type* ptr, const char* file, int line )
> {
> return TrackNewHelper<T>::TrackNew( ptr, file, line );
> }
>
> #define NEW( T ) TrackNew<T>( new T, __FILE__, __LINE__ )

VC6 (or, rather, MSC12) can't cope with functions overloaded only by their
template parameters or their returntype. Example:

template<typename R> R get_value() { return R(); }

Normally, you could use it like this:

int i = get_value<int>();
double d = get_value<double>();

...which VC6 happily compiles and links, only to either call the int or
double variant at runtime. The other variant is simply not part of the
executable because it is a function with the same name and same parameters.

Now, the workaround for that is:

#if defined(_MSC_VER) && _MSC_VER<1300
// workaround for MSC12 not mangling template parameters into
// generated function symbols
template<typename R> R get_value( R* dummy=0) { return R(); }
#else
template<typename R> R get_value() { return R(); }
#endif

IOW, you artificially add a parameter to the function that uses the template
parameter, causing the compiler to emit different symbols for different
instantiations.

I hope I understood your problem correctly, the problem is your code
contains too much additional stuff and lacks an error description...

good luck!

Uli


Re: VC++ 6.0 workaround for partial specialization by Matthias

Matthias
Mon Oct 29 04:22:52 PDT 2007

Thanks for the quick replay! The problem concerns the partial
specializations in my code, here it is again with error descriptions at the
corresponding lines:

#include <cstddef>
#include <iostream>

template <class T>
struct extract { typedef T type; };

// error C2989: 'A<T,2>' : template class has already been
// defined as a non-template class
// error C2988: unrecognizable template declaration/definition
template <class T, size_t N>
struct extract<T[N]> { typedef T type; };

template <class T> struct TrackNewHelper
{
static T* TrackNew( T* ptr, const char* file, int line)
{
std::cout << "Tracking object allocation" << std::endl;
return ptr;
}
};

// error C2989: 'A<T,2>' : template class has already been
// defined as a non-template class
// error C2988: unrecognizable template declaration/definition
template <class T, size_t N> struct TrackNewHelper<T[N]>
{
static T* TrackNew( T* ptr, const char* file, int line)
{
std::cout << "Tracking array allocation " << std::endl;
return ptr;
}
};

template <class T> typename extract<T>::type* TrackNew(
typename extract<T>::type* ptr, const char* file, int line )
{
return TrackNewHelper<T>::TrackNew( ptr, file, line );
}

#define NEW( T ) TrackNew<T>( new T, __FILE__, __LINE__ )

int main()
{
int * p = NEW( int );
delete p;

p = NEW( int[64] );
delete [] p;

return 0;
}

The problem is also described here:
http://support.microsoft.com/kb/240866/en-us

--
Matthias Hofmann
Anvil-Soft, CEO
http://www.anvil-soft.com - The Creators of Toilet Tycoon
http://www.anvil-soft.de - Die Macher des Klomanagers



Re: VC++ 6.0 workaround for partial specialization by Alexander

Alexander
Mon Oct 29 09:02:49 PDT 2007

The other advice still stands - get a modern C++ compiler.
VC 7.1 (part of VS 2003) is the earliest VC compiler that
supports partial template specialization. Current version is
VC 8.0 (VS 2005), and VC 9.0 (VS 2008) is right around
the corner. If you weren't in a hurry I'd have advised waiting
for VC 9.0 since it's supposed to reinvigirate C++ coding
with much improved MFC support. Not an option for you
I suppose...

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnickolov@mvps.org
MVP VC FAQ: http://vcfaq.mvps.org
=====================================

"Matthias Hofmann" <hofmann@anvil-soft.com> wrote in message
news:5olu5eFn5fd7U1@mid.individual.net...
> Thanks for the quick replay! The problem concerns the partial
> specializations in my code, here it is again with error descriptions at
> the corresponding lines:
>
> #include <cstddef>
> #include <iostream>
>
> template <class T>
> struct extract { typedef T type; };
>
> // error C2989: 'A<T,2>' : template class has already been
> // defined as a non-template class
> // error C2988: unrecognizable template declaration/definition
> template <class T, size_t N>
> struct extract<T[N]> { typedef T type; };
>
> template <class T> struct TrackNewHelper
> {
> static T* TrackNew( T* ptr, const char* file, int line)
> {
> std::cout << "Tracking object allocation" << std::endl;
> return ptr;
> }
> };
>
> // error C2989: 'A<T,2>' : template class has already been
> // defined as a non-template class
> // error C2988: unrecognizable template declaration/definition
> template <class T, size_t N> struct TrackNewHelper<T[N]>
> {
> static T* TrackNew( T* ptr, const char* file, int line)
> {
> std::cout << "Tracking array allocation " << std::endl;
> return ptr;
> }
> };
>
> template <class T> typename extract<T>::type* TrackNew(
> typename extract<T>::type* ptr, const char* file, int line )
> {
> return TrackNewHelper<T>::TrackNew( ptr, file, line );
> }
>
> #define NEW( T ) TrackNew<T>( new T, __FILE__, __LINE__ )
>
> int main()
> {
> int * p = NEW( int );
> delete p;
>
> p = NEW( int[64] );
> delete [] p;
>
> return 0;
> }
>
> The problem is also described here:
> http://support.microsoft.com/kb/240866/en-us
>
> --
> Matthias Hofmann
> Anvil-Soft, CEO
> http://www.anvil-soft.com - The Creators of Toilet Tycoon
> http://www.anvil-soft.de - Die Macher des Klomanagers
>
>



Re: VC++ 6.0 workaround for partial specialization by Matthias

Matthias
Tue Oct 30 07:07:08 PDT 2007

"Alexander Nickolov" <agnickolov@mvps.org> schrieb im Newsbeitrag
news:uL$QLUkGIHA.5328@TK2MSFTNGP05.phx.gbl...
> The other advice still stands - get a modern C++ compiler.
> VC 7.1 (part of VS 2003) is the earliest VC compiler that
> supports partial template specialization. Current version is
> VC 8.0 (VS 2005), and VC 9.0 (VS 2008) is right around
> the corner. If you weren't in a hurry I'd have advised waiting
> for VC 9.0 since it's supposed to reinvigirate C++ coding
> with much improved MFC support. Not an option for you
> I suppose...

Well, I am already using Visual C++ 2005 Express Edition, but our current
project is supposed to be compatible from Windows 95 through Windows Vista.
But talking about MFC: Everyone says that MFC is dead, so how come Microsoft
is going to reinvigorate it? Has the .NET bubble burst? ;-)

--
Matthias Hofmann
Anvil-Soft, CEO
http://www.anvil-soft.com - The Creators of Toilet Tycoon
http://www.anvil-soft.de - Die Macher des Klomanagers




Re: VC++ 6.0 workaround for partial specialization by Alexander

Alexander
Tue Oct 30 09:19:29 PDT 2007

It's hard to fight your own customers, so even Microsoft is
finally listening... It's not a coincidence that there are developers
who still use VC 6.0 despite the outdated compiler as the MFC
support deteriorated in VC 7.0. Personally I don't care much
about MFC preferring ATL + WTL, but I understand I'm a
minority.

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnickolov@mvps.org
MVP VC FAQ: http://vcfaq.mvps.org
=====================================

"Matthias Hofmann" <hofmann@anvil-soft.com> wrote in message
news:5oos5fFnmt5aU1@mid.individual.net...
> "Alexander Nickolov" <agnickolov@mvps.org> schrieb im Newsbeitrag
> news:uL$QLUkGIHA.5328@TK2MSFTNGP05.phx.gbl...
>> The other advice still stands - get a modern C++ compiler.
>> VC 7.1 (part of VS 2003) is the earliest VC compiler that
>> supports partial template specialization. Current version is
>> VC 8.0 (VS 2005), and VC 9.0 (VS 2008) is right around
>> the corner. If you weren't in a hurry I'd have advised waiting
>> for VC 9.0 since it's supposed to reinvigirate C++ coding
>> with much improved MFC support. Not an option for you
>> I suppose...
>
> Well, I am already using Visual C++ 2005 Express Edition, but our current
> project is supposed to be compatible from Windows 95 through Windows
> Vista. But talking about MFC: Everyone says that MFC is dead, so how come
> Microsoft is going to reinvigorate it? Has the .NET bubble burst? ;-)
>
> --
> Matthias Hofmann
> Anvil-Soft, CEO
> http://www.anvil-soft.com - The Creators of Toilet Tycoon
> http://www.anvil-soft.de - Die Macher des Klomanagers
>
>
>



Re: VC++ 6.0 workaround for partial specialization by Ben

Ben
Thu Nov 01 06:26:41 PDT 2007


"Matthias Hofmann" <hofmann@anvil-soft.com> wrote in message
news:5oos5fFnmt5aU1@mid.individual.net...
> "Alexander Nickolov" <agnickolov@mvps.org> schrieb im Newsbeitrag
> news:uL$QLUkGIHA.5328@TK2MSFTNGP05.phx.gbl...
>> The other advice still stands - get a modern C++ compiler.
>> VC 7.1 (part of VS 2003) is the earliest VC compiler that
>> supports partial template specialization. Current version is
>> VC 8.0 (VS 2005), and VC 9.0 (VS 2008) is right around
>> the corner. If you weren't in a hurry I'd have advised waiting
>> for VC 9.0 since it's supposed to reinvigirate C++ coding
>> with much improved MFC support. Not an option for you
>> I suppose...
>
> Well, I am already using Visual C++ 2005 Express Edition, but our current
> project is supposed to be compatible from Windows 95 through Windows
> Vista. But talking about MFC: Everyone says that MFC is dead, so how come
> Microsoft is going to reinvigorate it? Has the .NET bubble burst? ;-)

Not really, but the ".NET is the all-tool, universal solution to everything"
bubble has burst, and people realize that it's great for web applications
but for hardware control C and/or C++ still rule.

>
> --
> Matthias Hofmann
> Anvil-Soft, CEO
> http://www.anvil-soft.com - The Creators of Toilet Tycoon
> http://www.anvil-soft.de - Die Macher des Klomanagers
>
>
>