C ++: specialization of partial functions is not allowed for void - an alternative solution?

I think I understand why partial function templates are considered confusing and unnecessary and thus are not allowed by the C ++ standard. However, I would like some help in re-formulating the next function without partial specialization. FWIW, a function is a member of an unspecialized class:

template <typename IMPL, typename RET> RET call (functor <IMPL> func, IMPL * impl) { return func.call (impl); } template <typename IMPL> void call <IMPL, void_t> (functor <IMPL> func, IMPL * impl) { func.call (impl); } 

The problem is that I cannot overload the return type of the function. Also, the type name I want to specialize is not used as a parameter to the function - another reason why overloading doesn't help. Yes, I could introduce a dummy parameter to make it overload, but it's ugly, isn't it?

Finally, why is heck not a "void" type in C ++? That would make things a lot more consistent ... But I probably don't see the whole picture ...

+4
source share
5 answers

Firstly,

 template <typename IMPL, typename RET> RET call (functor <IMPL> func, IMPL * impl) { return func.call (impl); } 

really should be

 template <typename RET, typename IMPL> RET call (functor <IMPL> func, IMPL * impl) { return func.call (impl); } 

(I inverted RET and IMPL in the template argument list) so that you can call a function like

 call<int>(f, impl); 

instead of typing

 call<impl_type, int>(f, impl); 

In fact, the compiler cannot output RET , so you must provide it yourself.

Secondly, you do not need to overload void , since it is normal to return a void expression. If you want, you can add overload:

 template <typename IMPL> void call(functor<IMPL> func, IMPL* impl) 

and use call(f, impl) when calling this overload.

If you have access to C ++ 0x, consider using decltype .

+2
source

I believe that, firstly, if you have a function that returns void, then it is completely legal for the return expression to be void, such as calling another function that returns void, and secondly, void is full enter in C + +, and you can pass it into templates as much as you want.

+7
source

If your functor template class already has a typedef for RET, you can do this instead:

 template <typename IMPL> typename functor<IMPL>::RET call (functor <IMPL> func, IMPL * impl) { return func.call (impl); } 

and don’t worry about overload. Also, what are you using for the compiler? All standard compilers allow you to return the result of the void function from the void function.

+2
source

A general solution for partial specialization of functions involves using a helper class template with the same template arguments with a single method with the same arguments as your function. Then, the template class can be partially specialized.

In your case, however, I think you should use void as the return type, as indicated in other answers.

+2
source

You can do this using the overload function:

 template <typename IMPL, typename RET> RET call (functor <IMPL> func, IMPL * impl) { return func.call (impl); } template <typename IMPL> void call (functor <void_t> func, void_t * impl) { func.call (impl); } 

In addition, void is a type in C ++; what makes you think that this is not so?

+1
source

All Articles