Let's say you have some kind of target class with some methods on it:
class Subject { public: void voidReturn() { std::cout<<__FUNCTION__<<std::endl; } int intReturn() { std::cout<<__FUNCTION__<<std::endl; return 137; } };
And the Value class (similar to Boost.Any):
struct Value { Value() {} Value( Value const & orig ) {} template< typename T > Value( T const & val ) {} };
And I want to create a Value object using the method from the Subject class:
Subject subject; Value intval( subject.intReturn() ); Value voidVal( subject.voidReturn() );
In VC ++ 2008, the following errors occur:
error C2664: 'Value::Value(const Value &)' : cannot convert parameter 1 from 'void' to 'const Value &' Expressions of type void cannot be converted to other types
and gcc 4.4.3:
/c/sandbox/dev/play/voidreturn/vr.cpp:67: error: invalid use of void expression
The context for this is when you want to use it inside a template:
template< typename Host, typename Signature > class Method;
Using this Method class for a method returning something (namely intReturn) would look like this:
Method< Subject, int () > intMeth( &subject, &Subject::intReturn ); Value intValue = intMeth();
However, by doing this using the voidReturn method:
Method< Subject, void () > voidMeth( &subject, &Subject::voidReturn ); Value voidValue = voidMeth();
gives similar errors as stated above.
One solution is to further partially specialize the method for return types:
template< typename Host > class Method< Host, void () > { public: typedef void Return; typedef Return (Host::*MethodType)(); Method( Host * host, MethodType method ) : m_Host(host), m_Method(method) {} Value operator()() { return (m_Host->*m_Method)(), Value(); } private: Host * m_Host; MethodType m_Method; };
Also, it's just ugly, I also want to specialize the Method class for X signature parameter numbers, which already includes a lot of code duplication (hopefully Boost.Preprocessor can help here), and then adding specialization for void return types only double that effort duplication.
Anyway, to avoid this second specialization for void return types?