I am trying to implement a template function with handles void differently using template specialization.
The following code gives me an \"Explicit specialization in non
You can declare the explicit specialisation in the same way you'd define a member function outside of its class:
class A
{
public:
template <typename T>
static void foo () {}
};
template <>
void A::foo<void> ()
{
}
When you specialize a templated method, you must do so outside of the class brackets:
template <typename X> struct Test {}; // to simulate type dependency
struct X // class declaration: only generic
{
template <typename T>
static void f( Test<T> );
};
// template definition:
template <typename T>
void X::f( Test<T> ) {
std::cout << "generic" << std::endl;
}
template <>
inline void X::f<void>( Test<void> ) {
std::cout << "specific" << std::endl;
}
int main()
{
Test<int> ti;
Test<void> tv;
X::f( ti ); // prints 'generic'
X::f( tv ); // prints 'specific'
}
When you take it outside of the class, you must remove the 'static' keyword. Static keyword outside of the class has a specific meaning different from what you probably want.
template <typename X> struct Test {}; // to simulate type dependency
template <typename T>
void f( Test<T> ) {
std::cout << "generic" << std::endl;
}
template <>
void f<void>( Test<void> ) {
std::cout << "specific" << std::endl;
}
int main()
{
Test<int> ti;
Test<void> tv;
f( ti ); // prints 'generic'
f( tv ); // prints 'specific'
}
I had a similar problem. If you look at the original post, I left the first static in, but took out the second and BOTH errors went away.
It's not directly an answer to your question but you can write this
template <typename T>
static T safeGuiCall(boost::function<T ()> _f)
{
if (_f.empty())
throw GuiException("Function pointer empty");
{
ThreadGuard g;
return _f();
}
}
It should work even if _f() return 'void'
Edit : In a more general case, I think we should prefer function overloading instead of specialization. Here is a good explanation for this : http://www.gotw.ca/publications/mill17.htm
Your problem appears to be with boost::function - the following specialisations work:
template <typename T>
T safeGuiCall()
{
return T();
}
template <>
void safeGuiCall<void>()
{
}
int main() {
int x = safeGuiCall<int>(); // ok
//int z = safeGuiCall<void>(); // this should & does fail
safeGuiCall<void>(); // ok
}