tags:

views:

94

answers:

2

I have a template class in which I am specializing a couple of methods. For some reason, when I added a specialization for a struct, it seems to be conflicting with the specialization for bool. I am getting a type conversion error because it is trying to set the struct = bool (resolving to the wrong specialization). Here is some code

.h:

typedef struct foo {
  ...
}

template <class T> class bar {
   template <class T> void method1() {...}
   template <> void method1<bool>() {...}
   template <> void method1<foo>() {...}
}

.cpp

 template class bar<bool>;
 template class bar<foo>;

I am getting the error inside method1<bool> because it is setting T=foo instead of resolving it to method1<foo>.

Any ideas?

+3  A: 

The first part of your code is already incorrect. C++ does not support explicit specialization of "nested" (member) templates without explicit specialization of the enclosing template.

In the context of your code, it is illegal to explicitly specialize template method method1 without explicitly specializing the entire class template bar.

If your member template function member1 depended on some parameters, you could use overloading instead of template specialization as a workaround. But since it doesn't, you have to redesign you templates somehow. What you do above is, once again, illegal in C++.

The errors you get further down can easily be (and most probably are) induced by that original problem.

P.S. The description of the problem you posted implies that your code compiles. What you posted should not compile for the reasons described above. This suggests that you are posting fake code. Post real code.

AndreyT
Actually, this was working fine with other types. I only got the error once I added the struct specialization.
AdamC
@AdamC: Sometimes a compiler will admit code that is not standard-conforming -- possibly that's the case here. For obvious reasons it's very dangerous to depend on this behaviour.
j_random_hacker
@AdamC: That simply means that your compiler offers you some extended capabilities that really have not much to do with C++ language. It is hard to predict how that capability is supposed to work, since it is not governed by the language. Maybe what you observe is the intended behavior, maybe not... Consult your compiler's documentation, since, once again, this is not C++.
AndreyT
+1  A: 

(EDITED)

You may try the following, which delegates the method implementation to a templated helper class.

.h:

typedef struct Foo {
  ...
}

template<class T_Bar, class T2> struct BarMethod1;
template <class T> class Bar 
{
   template<class T2> void method1(...)
   {
      BarMethod1<Bar, T2>(...)(...);
   }
}
template <class T_Bar, class T2> class BarMethod1 
   {void operator()(...){...}};
template <class T_Bar> class BarMethod1<T_Bar, bool>
   {void operator()(...){...}};

template <class T_Bar> BarMethod1<T_Bar, Foo>
   {void operator()(...){...}};

.cpp

 template class Bar<bool>;
 template class BarMethod1<Bar<bool>, bool>;
 template class BarMethod1<Bar<bool>, Foo>;
 template class Bar<Foo>;
 template class BarMethod1<Bar<Foo>, bool>;
 template class BarMethod1<Bar<Foo>, Foo>;
Benoît
Suffers from exactly the same problem: attempts to explicitly specialize the inner template without specializing the outer one. Even if some compiler accepts it, it is still not valid C++.
AndreyT
Really ? I am surprised, but i don't argue ; i am no standard expert.
Benoît
How about this new version ?
Benoît
The standard discussion is interesting, but to me, only as a side-note. Code that compiles and works on recent gcc and VS is more important to me. @Benoit - thanks for the help!
AdamC