www.digitalmars.com         C & C++   DMDScript  

c++ - Member template functions and specialization

reply Christof Meerwald <cmeerw web.de> writes:
Here is an example taken from the C++ standard (14.5.2 (2), see
http://www.dfv.rwth-aachen.de/doc/c++std/template.html#temp.mem):

template <class T>
struct A
{
  void f(int);
  template <class T2> void f(T2);
};

template <> void A<int>::f(int)
{ }

template <> template <> void A<int>::f<>(int)
// Error: 'f' is not a class template
{ }

int main()
{
  A<char> ac;
  ac.f(1);
  ac.f('c');
  ac.f<>(1);
}


bye, Christof

-- 
http://cmeerw.org                                 JID: cmeerw jabber.at
mailto cmeerw at web.de

...and what have you contributed to the Net?
Nov 24 2002
parent reply Richard <fractal clark.net> writes:
In article <arqv7o$eqp$2 digitaldaemon.com>, Christof Meerwald says...
Here is an example taken from the C++ standard (14.5.2 (2), see
http://www.dfv.rwth-aachen.de/doc/c++std/template.html#temp.mem):
I have something similiar with member templates, but I'm not nearly as certain that its not some problem on my end ;) Ok, the following works, and you get a value of 1 as the output.I think the definition is a little whacked because it does not specify f<T>(T& i).. but it works. The problems occur later when the member template definition is moved to another translation unit. Here's what works in the same unit. #include <iostream> struct A { template<typename T> void f(T& i); }; template<typename T> void A::f(T& i) { ++i; } void main(int argc, char *argv[]) { A a; int j = 0; a.f(j); cout << "j is " << j << endl; } Now if you move the struct definition and the member template definition to .h and .cpp respectively, the project compiles, but is unable to find f() on link.. link fails with undefined symbol like: : Symbol Undefined ??$f A H A QAEXAAH Z If you change the main accessor to f<int>(j), and the member template declaration to f<T>(T& i), and the definition to use f<T>(T& i), the compiler unhappily reports back an error concerning the accessor in main stating it needs a "(" following a simple type name. Returning that to what it was causes the next item to fail with f is not a member template. Then the final change fails with f is not a member template. Changing this brings back symbol undefined.. Generally, I find that member templates need to be defined in the class definition. This is the setup I used to generate the linker undefined symbol notice -> test.h ------ struct A { template<typename T> void f(T& i); }; test.cpp -------- #include "test.h" template<typename T> void A::f(T& i) { ++i; } testtemplate.cpp ---------------- #include <iostream> #include "test.h" void main(int argc, char *argv[]) { A a; int j = 0; a.f(j); cout << "j is " << j << endl; } Richard
Nov 26 2002
parent reply "Walter" <walter digitalmars.com> writes:
You need to include the body of the template in any compilation unit that
needs to instantiate the template. -Walter


"Richard" <fractal clark.net> wrote in message
news:as0ph3$t9t$1 digitaldaemon.com...
 In article <arqv7o$eqp$2 digitaldaemon.com>, Christof Meerwald says...
Here is an example taken from the C++ standard (14.5.2 (2), see
http://www.dfv.rwth-aachen.de/doc/c++std/template.html#temp.mem):
I have something similiar with member templates, but I'm not nearly as
certain
 that its not some problem on my end ;) Ok, the following works, and you
get a
 value of 1 as the output.I think the definition is a little whacked
because it
 does not specify f<T>(T& i).. but it works. The problems occur later when
the
 member template definition is moved to another translation unit. Here's
what
 works in the same unit.

 #include <iostream>

 struct A {
 template<typename T> void f(T& i);
 };

 template<typename T>
 void A::f(T& i) { ++i; }

 void main(int argc, char *argv[]) {
 A a;
 int j = 0;
 a.f(j);
 cout << "j is " << j << endl;
 }

 Now if you move the struct definition and the member template definition
to .h
 and .cpp respectively, the project compiles, but is unable to find f() on
link..
 link fails with undefined symbol like:

 : Symbol Undefined ??$f A H A  QAEXAAH Z

 If you change the main accessor to f<int>(j), and the member template
 declaration to f<T>(T& i), and the definition to use f<T>(T& i), the
compiler
 unhappily reports back an error concerning the accessor in main stating it
needs
 a "(" following a simple type name. Returning that to what it was causes
the
 next item to fail with f is not a member template. Then the final change
fails
 with f is not a member template. Changing this brings back symbol
undefined..
 Generally, I find that member templates need to be defined in the class
 definition.

 This is the setup I used to generate the linker undefined symbol notice ->

 test.h
 ------
 struct A {
 template<typename T> void f(T& i);
 };

 test.cpp
 --------
 #include "test.h"

 template<typename T>
 void A::f(T& i) { ++i; }

 testtemplate.cpp
 ----------------
 #include <iostream>

 #include "test.h"

 void main(int argc, char *argv[]) {
 A a;
 int j = 0;
 a.f(j);
 cout << "j is " << j << endl;
 }

 Richard
Nov 26 2002
parent reply Richard <fractal clark.net> writes:
In article <as0qgn$ud7$1 digitaldaemon.com>, Walter says...
You need to include the body of the template in any compilation unit that
needs to instantiate the template. -Walter
Thanks. Is that in general or specific to DM for the moment? Richard
Nov 26 2002
parent "Walter" <walter digitalmars.com> writes:
"Richard" <fractal clark.net> wrote in message
news:as0ulb$131g$1 digitaldaemon.com...
 In article <as0qgn$ud7$1 digitaldaemon.com>, Walter says...
You need to include the body of the template in any compilation unit that
needs to instantiate the template. -Walter
Thanks. Is that in general or specific to DM for the moment?
I believe it is true in general, unless the compiler supports "export"ed templates, which use a different syntax.
Nov 26 2002