Template specialization and Visual C++

I've written the following code under g++ compiler, it works without problems.
But when I try to compile it with Visual C++ 6, it doesn't work :

the mistake is:
line 22 error C2989: 'trait<class GraphImpl<T,`template-parameter258'> >' : template class has already been defined as a non-template class

the code is :
1     #include "stdio.h"
2
3
4     template <class EdgeType, class NodeType >
5     class GraphImpl
6     {
7      public:
8          GraphImpl()
9          {}
10    };
11
12    struct undefined_type {};
13
14    template <class T>
15    struct trait
16    {
17      typedef undefined_type type1;
18      typedef undefined_type type2;
19    };
20
21    template <class EdgeType, class NodeType>
22    class trait < GraphImpl < EdgeType, NodeType > >
23    {
24    public :
25      typedef EdgeType type1;
26      typedef NodeType type2;
27    };
28
29
30    int main()
31    {
32      trait<GraphImpl<int, int> >::type1 i;
33    }

Do you know how to make it compile ???

LVL 6
stsanzAsked:
Who is Participating?
 
jkrConnect With a Mentor Commented:
>>Do you know how to make it compile ???

It simply does not work with VC++ 6.0 - see http://support.microsoft.com/default.aspx?scid=KB;en-us;240866& ("BUG: ERROR C2989 and C2988 on Class Template Partial Specializations")

SYMPTOMS
You may get the following error message if you try to use class template partial specializations:

error C2989: 'A<T,2>' : template class has already been defined as a non-template class error C2988: unrecognizable template declaration/definition
Please refer to the sample in the More Information section for details.

CAUSE
The compiler does not support class template partial specializations as specified in the C++ Standard (14.5.4.1) quoted here:
0
 
burcarpatCommented:
jkr is right; you can't do it in msvc6 but there is a workaround  

basically, you need to find all possible GraphImpl combinations ( such as int, int ) and fully specialize them for the trait class.  if you have around 20-10 combinations and if it's unlikely that you'll add more, this is a reasonable solution and won't require any more code change than adding full specializations

--- cut from here ---
template <
  class EdgeType,
     class NodeType
  >
class GraphImpl {
public:
  GraphImpl()
      { }
};

struct undefined_type {};

template <class T>
struct trait {
  typedef undefined_type type1;
  typedef undefined_type type2;
     enum { test = 123 };
};

template <>
struct trait < GraphImpl<int, int> > {
public :
  typedef int type1;
  typedef int type2;
  enum { test = 456 };
};

template <>
struct trait < GraphImpl<double, double> > {
public :
  typedef int type1;
  typedef int type2;
  enum { test = 789 };
};

int
main(int argc, char* argv[]) {

  std::cout << trait<GraphImpl<int, int> >::test << std::endl;
  std::cout << trait<GraphImpl<double, double> >::test << std::endl;

  trait<GraphImpl<int, int> >::type1 i;
     
  return 0;
}
--- cut from here ---
0
 
burcarpatCommented:
ooops, i meant "2-10 combinations" ;-)
0
 
burcarpatCommented:
and, of course, the second trait should have been,

template <>
struct trait < GraphImpl<double, double> > {
public :
 typedef double type1;
 typedef double type2;
 enum { test = 789 };
};

see, why it won't work if you have more than 10 such specializations?  maintenance is a nightmare.  heck, i can't even maintain two of 'em ;-)
0
All Courses

From novice to tech pro — start learning today.