Template member functions in template class with separate definition

  • Thread starter =?iso-8859-1?q?Erik_Wikstr=F6m?=
  • Start date

?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

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?
 
Ad

Advertisements

S

Steven T. Hatton

Erik said:
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.
 
?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

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

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

Steven T. Hatton

Erik said:
#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
 
G

Greg

Erik said:
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;

}

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
 
Ad

Advertisements

?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

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?

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 = 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 = 5;
return *this;
}

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

}

Once again, the "template<template<class U = 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.
 
Ad

Advertisements


Top