I have the following code that I hope to simplify and minimize duplication.
// Gather.cpp
void GetParam()
{
ProParameter * param; // 3rd party struct
ProParamvalue proValue; // 3rd party struct
ProParameterValueGet( param, & proValue ); // this is a call to a 3rd Party API
shared_ptr< CPartParam > pParam; // CPartParam is my class
/* The .type in switch() statement is an enum with following definition:
typedef enum param_value_types {
PRO_PARAM_DOUBLE = 50, /* use d_val from ProParamvalueValue to set value *
PRO_PARAM_STRING = 51, /* use s_val from ProParamvalueValue to set value *
} ProParamvalueType;
*/
// WUD LOVE TO ELIMINATE THE SWITCH-CASE
switch( proValue.type ) // .type is enum as above
{
case PRO_PARAM_DOUBLE: // 3rd party enum value
pParam->SetValue( proValue.value.d_val );
break;
case PRO_PARAM_STRING: // 3rd party enum value
pParam->SetValue( proValue.value.s_val );
break;
default:
break;
}
}
// PartData.h
class CPartParam
{
public:
enum ValueType
{
DOUBLE,
STRING
};
ValueType m_eValueType;
double m_dVal;
wstring m_sVal;
bool SetValue( const double & dVal );
bool SetValue( const wstring & sVal );
};
// PartData.cpp
// There is one overload for each data-type. WUD LOVE TO CONDENSE TO A SINGLE METHOD/TEMPLATE FUNCTION THAT CAN SET THE VALUE IRRESPECTIVE OF THE DATA-TYPE.
void CPartParam::SetValue( const double & dVal )
{
m_eValueType = DOUBLE;
m_dVal = dVal;
}
bool CPartParam::SetValue( const wstring & sVal )
{
m_eValueType = STRING;
m_sVal = sVal;
}
As can be seen the datatype of the "proValue.type" is determined at runtime, which forces me to write repetitive code: CPartParam::SetValue() overloads (one for each data-type). I would LOV开发者_JAVA百科E it if I can avoid the switch-case loop in GetParam(), if at all possible.
There is more repetitive code with a 2nd switch-case when the data stored in CPartParam shared_ptr has to retrieved (i.e. CPartParam::GetValue).
I have shown sample code (may not necessarily compile), but will fix if anyone wants to compile.
I have shown only two data-types (PRO_PARAM_DOUBLE, PRO_PARAM_STRING) but there are a handful more.
The only restrictions I have are that our dev team still uses Boost 1.36.0, Visual Studio 2005 (primary reason is due to the 3rd party library). We need to use boost::serialization, so recommendations to use any new data-types has the restriction that that new data-type must be serializable using boost::serialization in boost version 1.36.0.
Have a look at Boost.Variant (which is available in Boost 1.36.0). This provides a variant
type that encapsulates the discriminated union (taking the place of your CPartParam
type), and a static_visitor
idiom that takes the place of the switch.
You are looking for run-time inheritance. The best solution really is a boost::variant
, which is nicely optimized and such.
精彩评论