Template member functions in template class with separate definition

  • Follow


The following code works:

#include <iostream>

template<class T>
struct Test
{
	T t;
	template<class T, template<class U =3D T> class V>
	Test<T>& foo(V<T>& f)
	{
		f.t =3D 5;
		return *this;
	}
};

int main() {
	Test<int> t;
	t.foo(t);
	std::cout << t.t;

}

However, if I try to move the definition of the foo()-function outside
of the declaration like so:

template<typename T, template<typename U =3D T> class V>
Test<T>& Test<T>::foo(V<T>& f)
{
	f.t =3D 5;
	return *this;
}

It does not compile (VC++8.0) with the following error-message:

test.cpp(24) : error C2244: 'Test<T>::foo' : unable to match function
definition to an existing declaration
        definition
        'Test<T> &Test<T>::foo(V<T> &)'
        existing declarations
        'Test<T> &Test<T>::foo(V<T> &)'

Anyone have an idea of how to make this work?

--
Erik Wikstr=F6m

0
Reply eriwik (500) 12/14/2006 11:56:34 AM

Erik Wikstr�m wrote:

> The following code works:
> 
> #include <iostream>
> 
> template<class T>
> struct Test
> {
> T t;
> template<class T, template<class U = T> class V>
> Test<T>& foo(V<T>& f)
> {
> f.t = 5;
> return *this;
> }
> };
> 
> int main() {
> Test<int> t;
> t.foo(t);
> std::cout << t.t;
> 
> }
> 
> However, if I try to move the definition of the foo()-function outside
> of the declaration like so:
> 
> template<typename T, template<typename U = T> class V>
> Test<T>& Test<T>::foo(V<T>& f)
> {
> f.t = 5;
> return *this;
> }
> 
> It does not compile (VC++8.0) with the following error-message:
> 
> test.cpp(24) : error C2244: 'Test<T>::foo' : unable to match function
> definition to an existing declaration
>         definition
>         'Test<T> &Test<T>::foo(V<T> &)'
>         existing declarations
>         'Test<T> &Test<T>::foo(V<T> &)'
> 
> Anyone have an idea of how to make this work?

The default argument in the function _definition_ looks wrong to me.

-- 
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
0
Reply chattengau (616) 12/14/2006 12:03:36 PM


On Dec 14, 1:03 pm, "Steven T. Hatton" <chatten...@germania.sup> wrote:
> Erik Wikstr=F6m wrote:
> > The following code works:
>
> > #include <iostream>
>
> > template<class T>
> > struct Test
> > {
> > T t;
> > template<class T, template<class U =3D T> class V>
> > Test<T>& foo(V<T>& f)
> > {
> > f.t =3D 5;
> > return *this;
> > }
> > };
>
> > int main() {
> > Test<int> t;
> > t.foo(t);
> > std::cout << t.t;
>
> > }
>
> > However, if I try to move the definition of the foo()-function outside
> > of the declaration like so:
>
> > template<typename T, template<typename U =3D T> class V>
> > Test<T>& Test<T>::foo(V<T>& f)
> > {
> > f.t =3D 5;
> > return *this;
> > }
>
> > It does not compile (VC++8.0) with the following error-message:
>
> > test.cpp(24) : error C2244: 'Test<T>::foo' : unable to match function
> > definition to an existing declaration
> >         definition
> >         'Test<T> &Test<T>::foo(V<T> &)'
> >         existing declarations
> >         'Test<T> &Test<T>::foo(V<T> &)'
>
> > Anyone have an idea of how to make this work?
>
>The default argument in the function _definition_ looks wrong to me.

You mean the U =3D T part? I tried with "template<class T,
template<class> class V>" instead but with no luck.

--
Erik Wikstr=F6m

0
Reply eriwik (500) 12/14/2006 12:19:51 PM

Erik Wikstr�m wrote:

> #include <iostream>
> 
> template<class T>
> struct Test
> {
> T t;
> template<class T, template<class U = T> class V>
> Test<T>& foo(V<T>& f)
> {
> f.t = 5;
> return *this;
> }
> };
> 
> int main() {
> Test<int> t;
> t.foo(t);
> std::cout << t.t;
> 
> }
> 
> However, if I try to move the definition of the foo()-function outside
> of the declaration like so:
> 
> template<typename T, template<typename U = T> class V>
> Test<T>& Test<T>::foo(V<T>& f)
> {
> f.t = 5;
> return *this;
> }
The first form doesn't compile for me with GCC 4.0.2.  Have I got it right?

//templ.cpp
#include <iostream>

template<class T>
struct Test
{
  T t;
  template<class T, template<class U = T> class V>
  Test<T>& foo(V<T>& f)
  {
    f.t = 5;
    return *this;
  }
};

int main() {
  Test<int> t;
  t.foo(t);
  std::cout << t.t;
}
//---------------EOF-----------------

g++ -o templ templ.cpp
templ.cpp:7: error: declaration of ?class T?
templ.cpp:3: error:  shadows template parm ?class T?

Compilation exited abnormally with code 1 at Thu Dec 14 07:47:26

-- 
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
0
Reply chattengau (616) 12/14/2006 12:52:10 PM

Erik Wikstr=F6m wrote:
> The following code works:
>
> #include <iostream>
>
> template<class T>
> struct Test
> {
> 	T t;
> 	template<class T, template<class U =3D T> class V>
> 	Test<T>& foo(V<T>& f)
> 	{
> 		f.t =3D 5;
> 		return *this;
> 	}
> };
>
> int main() {
> 	Test<int> t;
> 	t.foo(t);
> 	std::cout << t.t;
>
> }

The program is using "T" as the name of two separate type parameters,
So I would suggest giving each parameter a distinct name, maybe T1 and
T2, so that the compiler can tell them part.

Greg

0
Reply greghe (676) 12/14/2006 1:00:46 PM

On Dec 14, 1:52 pm, "Steven T. Hatton" <chatten...@germania.sup> wrote:
>
>The first form doesn't compile for me with GCC 4.0.2.  Have I got it right?
>
> //templ.cpp
> #include <iostream>
>
> template<class T>
> struct Test
> {
>   T t;
>   template<class T, template<class U =3D T> class V>
>   Test<T>& foo(V<T>& f)
>   {
>     f.t =3D 5;
>     return *this;
>   }
>
> };int main() {
>   Test<int> t;
>   t.foo(t);
>   std::cout << t.t;}//---------------EOF-----------------
>
> g++ -o templ templ.cpp
> templ.cpp:7: error: declaration of ?class T?
> templ.cpp:3: error:  shadows template parm ?class T?

Yes, that looks right, however I finally managed to find a working
solution:

#include <iostream>

template<class T>
struct Test
{
	T t;
	template<template<class U =3D T> class V>
	Test<T>& foo(V<T>& f);
};

template<class T>
template<template<class> class V>
Test<T>& Test<T>::foo(V<T>& f)
{
	f.t =3D 5;
	return *this;
}

int main() {
	Test<int> t;
	t.foo(t);
	std::cout << t.t;

}

Once again, the "template<template<class U =3D T> class V>" can be
reduced to "template<template<class> class V>" but I think that it
documents the intention that the type that V is parametrized by is the
same as that of Test.

--
Erik Wikstr=F6m

0
Reply eriwik (500) 12/14/2006 1:04:38 PM

5 Replies
18 Views

(page loaded in 0.078 seconds)

Similiar Articles:













7/18/2012 2:13:52 PM


Reply: