0

次のようなコンテナバリアントがあります。

typedef boost::variant<std::vector<int>, std::vector<std::string> > Container;

そして、次のように、ValueContainer オブジェクト (C 構造体) から Container オブジェクトを作成します。

class ContainerAppender: public boost::static_visitor<>
{
public:
    void setValueToAppend(const Value* value){
        _value = value;
    }

    void operator()(std::vector<int>& container) const {
        container.push_back(_value->value.i);
    }

    void operator()(std::vector<std::string>& container) const {
        container.push_back(_value->value.s);
    }

    ...

private:
    const Value* _value;
};

void fillContainer(Container& container, ValueContainer* cContainer) {
    if(cContainer) {
        ContainerAppender append;
        for(int i = 0; i < cContainer->nunberOfValues; i++) {
            append.setValueToAppend(&cContainer->values[i]);
            boost::apply_visitor(append, container);
        }
    }
}

C 構造を自由に変更することはできません。

コンテナーの種類が決して変わらないという事実にもかかわらず、ループごとにアクセスしているため、コンテナーにデータを入力するためのソリューションが好きではありません。もっと良い方法があるように感じます。手伝ってくれますか?

Cユニオンは次のとおりです。

typedef struct Value {
    union {
        int   i;
        const char* s;
    } value;
} Value_T;

typedef struct ValueContainer {
    Type type;
    unsigned int numberOfValues;
    Value *values;
} ValueContainer_T;
4

1 に答える 1

1

訪問者は本当に必要ですか?このことを考慮:

template<typename T>
T value_get(Value_T const &c_variant) {
    return T();
}

template<>
int value_get<int>(Value_T const &c_variant) {
    return c_variant.i;
}

template<>
const char* value_get<const char*>(Value_T const &c_variant) {
    return c_variant.s;
}

template<typename T> 
std::vector<T> fill_vector(ValueContainer_T const& c_container) {
    std::vector<T> cpp_container(c_container.numberOfValues);
    for(size_t i = 0; i < c_container.numberOfValues; ++i)
        cpp_container[i] = value_get<T>(c_container.values[i]);
    return cpp_container;
}

私にはもっと簡単に見えます。

于 2013-05-24T09:07:50.003 に答える