So I guess that I need to put the specialization of foo<0> somewhere
out of the class definition, but what is the correct syntax to do
that?
Thanks a lot
template <class A>
class MyClass
{
template <unsigned char N>
void foo( sie_t int ) { /* ... */ }
template <>
void foo<0>( sie_t int ) { /* ... */ }
};
template <class A>
class MyClass
{
template <unsigned char N>
void foo( int x )
{
// ... do something
foo<N-1>( x );
}
template <>
void foo<0>( int x )
{
// do nothing: stops template expansion recursion
}
};
Yes. Have you tried the namespace scope? :-p
struct S
{
template<int N>
void foo(int k);
};
template<int N>
void S::foo(int k) {}
template<>
void S::foo<0>(int k) {}
Cheers!
SG
Is this also possible for the template function in the template class ?
Cheers!
ZikO
You mean "function template" and "class template". The answer is
yes. It's something along the lines of
template<typename T>
template<int N>
void S<T>::foo(int k) {}
template<typename T>
template<>
void S<T>::foo<0>(int k) {}
Cheers!
SG
I think specialization of method is not allowed.
Anyway, since the class had not that many members, I changed my design
putting the second template argument in the outer class. Then it
became easy to specialise it.
> yes. It's something along the lines of
>
> template<typename T>
> template<int N>
> void S<T>::foo(int k) {}
>
> template<typename T>
> template<>
> void S<T>::foo<0>(int k) {}
I have tried something as below:
//------------------------------------
#include <iostream>
template<class T> class A {
public:
template<size_t N> void f();
};
template<class T> template<size_t N> void A<T>::f() {
std::cout << N << std::endl;
}
template<class T> template<> void A<T>::f<0>() {
std::cout << "Stopping ..." << std::endl;
}
int main() {
A<int> a;
a.f<10>();
a.f<0>();
}
//------------------------------------
test2.cpp:10: error: invalid explicit specialization before '>' token
test2.cpp:10: error: enclosing class templates are not explicitly
specialized
test2.cpp:10: error: template-id 'f<0>' for 'void A<T>::f()' does not
match any template declaration
Well, as I found there was no matching f<0> to anything, I added
declaration in the class template, so appart from the class definition,
everything looks the same in the code:
//-------------------------------------
#include <iostream>
template<class T> class A {
public:
template<size_t N> void f();
template<> void f<0>();
};
template<class T> template<size_t N> void A<T>::f() {
std::cout << N << std::endl;
}
template<class T> template<> void A<T>::f<0>() {
std::cout << "Stopping ..." << std::endl;
}
int main() {
A<int> a;
a.f<10>();
a.f<0>();
}
//-------------------------------------
but it looks even worse:
test2.cpp:6: error: explicit specialization in non-namespace scope
'class A<T>'
test2.cpp:11: error: invalid explicit specialization before '>' token
test2.cpp:11: error: enclosing class templates are not explicitly
specialized
test2.cpp:11: error: template-id 'f<0>' for 'void A<T>::f()' does not
match any template declaration
So what do you think I am doing wrong here?
Cheers!
Ziko
I haven't tested member function specialization of a class template
and I thought it was supposed to work. Sorry for the trouble.
As a rule of thumb you should try to avoid specializing function
templates altogether. There are other alternatives (like overloading
function templates or turning a function template into a non-templated
member function of some class template).
Cheers!
SG
The second example is ill-formed. A member template can not be
explicitly (fully) specialized unless the enclosing class template is
also explicitly (fully) specialized.
template<>
template<>
void S<int>::foo<0>(int k) {} // ok
template<>
template<int N>
void S<int>::foo<0>(int k) {} // ok
template<typename T>
template<>
void S<T>::foo<0>(int k) {} // ill-formed
There's no immediate correct syntax for this. Explicit specialization of
a member template without explicit specialization of enclosing template
is not allowed in C++.
If the inner template was a class template, you could've worked around
this limitation by introducing a dummy parameter and using partial
specialization instead of explicit one. So, you can try wrapping your
'foo' into a class (as a static member) and applying this workaround
template <class A>
class MyClass
{
template <unsigned char N, unsigned char DUMMY = 0>
struct S
{
static void foo( int x ) { /* ... */ }
};
template <unsigned char DUMMY>
struct S<0, DUMMY>
{
static void foo( int x ) { /* ... */ }
};
};
This looks like workaround on workaround, and is generally ugly, but it
works.
--
Best regards,
Andrey Tarasevich
> The following syntax cause gcc to complain about:
> - explicit specialization in non-namespace scope
> - enclosing class templates are not explicitly specialized
Here's another workaround:
#include <iostream>
template <int i>
struct int_ { static const int value = i; };
// or #include <boost/mpl/int.hpp>
template <class A>
class MyClass {
private:
template <int N>
void foo(int x, int_<N>)
{
std::cout << N << ',';
foo(x, int_<N-1>());
}
// note overload, not specialization
void foo(int x, int_<0>)
{ std::cout << " x = " << x; }
public:
template <unsigned char N>
void foo(int x) { foo(x, int_<N>()); }
};
int main()
{
MyClass<float> m;
m.foo<3>(5);
return 0;
}
Martin
--
Quidquid latine scriptum est, altum videtur.