【问题标题】:C++ runtime datatype identification & avoiding switch-caseC++ 运行时数据类型识别和避免 switch-case
【发布时间】:2011-04-19 20:50:26
【问题描述】:

我有以下代码,希望能简化并尽量减少重复。

// 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;
}

可以看出“proValue.type”的数据类型是在运行时确定的,这迫使我编写重复代码:CPartParam::SetValue() 重载(每个数据类型一个)。如果我可以避免 GetParam() 中的 switch-case 循环,我会很高兴的。

当必须检索存储在 CPartParam shared_ptr 中的数据(即 CPartParam::GetValue)时,第二个 switch-case 的重复代码更多。

我已经展示了示例代码(可能不一定能编译),但如果有人想编译,我会修复。

我只展示了两种数据类型(PRO_PARAM_DOUBLE、PRO_PARAM_STRING),但还有更多。

我唯一的限制是我们的开发团队仍然使用 Boost 1.36.0,Visual Studio 2005(主要原因是由于 3rd 方库)。我们需要使用 boost::serialization,因此使用任何新数据类型的建议都有一个限制,即新数据类型必须在 boost 版本 1.36.0 中使用 boost::serialization 进行序列化。

【问题讨论】:

  • 您要消除哪些重复代码?
  • @john-dibling Whups。我想我应该更具体一些。编辑代码以显示重复。谢谢。

标签: c++


【解决方案1】:

看看 Boost.Variant(在 Boost 1.36.0 中可用)。这提供了一个封装了可区分联合的variant 类型(代替您的CPartParam 类型),以及一个代替开关的static_visitor 习惯用法。

【讨论】:

【解决方案2】:

您正在寻找运行时继承。最好的解决方案确实是boost::variant,它经过了很好的优化等等。

【讨论】:

    猜你喜欢
    • 2016-06-12
    • 1970-01-01
    • 1970-01-01
    • 2015-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多