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

 that its not some problem on my end ;) Ok, the following works, and you

 value of 1 as the output.I think the definition is a little whacked

 does not specify f<T>(T& i).. but it works. The problems occur later when

 member template definition is moved to another translation unit. Here's

 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

 and .cpp respectively, the project compiles, but is unable to find f() on

 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

 unhappily reports back an error concerning the accessor in main stating it

 a "(" following a simple type name. Returning that to what it was causes

 next item to fail with f is not a member template. Then the final change

 with f is not a member template. Changing this brings back symbol

 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