Topic: Template member function overload/specialization?


Author: James Garrison <jhg@acm.org>
Date: 1999/06/18
Raw View
I realize this problem has been discussed here recently, but my
searches through DejaNews haven't turned up anything that
directly addresses my question, so here goes:

 ///////////////////////////////////

  1 struct A
  2 {
  3  char * p;
  4  int n;
  5 };
  6
  7 template<class T, class U>
  8 class X
  9 {
 10 public:
 11  X() {}
 12  void foo(T t, U u) { cout << "Generic foo" << endl; }
 13  template<class U> void foo(A a, U u) { cout << "Specialized foo" <<
endl; }
 14 };
 15
 16 int main(int argc, char* argv[])
 17 {
 18  X<long,long> xll;
 19  X<A,long> xAl;
 20  A  a = {NULL,0};
 21  void * p=NULL;
 22
 23  xll.foo(1,1);
 24  xAl.foo(a,1);
 25  xAl.foo(a,p);
 26
 27  return 0;
 28 }

//////////////////////////////////////

What I want to accomplish is a "partially specialized" instance of
a template class' member function.  I believe this isn't directly
possible in C++, but can be approximated as shown above, with a
member function template that overloads the generic foo.

This method has a problem in that the <class U> in line 13 isn't the
same as the one in line 7.  This allow line 25 to compile successfully,
which is not what I want. If I change line 13 to

 13  template<> void foo(A a, U u) { cout << "Specialized foo" << endl;
}

it seems to have the desired semantics, but then the compiler
(MSVC++ 6 SP3) complains with:

C:\ED30\V300\test4\test4.cpp(13) : error C2535:
 'void __thiscall X<struct A,long>::foo(struct A,long)' :
 member function already defined or declared
        C:\ED30\V300\test4\test4.cpp(12) : see declaration of 'foo'
        C:\ED30\V300\test4\test4.cpp(19) : see reference to class
template
  instantiation 'X<struct A,long>' being compiled

C:\ED30\V300\test4\test4.cpp(25) : error C2664: 'foo' :
 cannot convert parameter 2 from 'void *' to 'long'
        This conversion requires a reinterpret_cast, a C-style cast
 or function-style cast

The first message is telling me that both the generic foo and
'specialized'
foo resolved to exactly the same signature, and the compiler is
confused.

The second message is correct for the desired semantics.  Since there is
no
X<A,void *>, this is, and should be, an error.

Question:  Is MSVC++ behaving correctly, or is this one of the esoteric
fine
points of the standard that MS didn't get right?

Thanks,

Jim Garrison
jhg@acm.org

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]