единое представление для немного разных структур - PullRequest
2 голосов
/ 04 августа 2020

У меня сложная структура, которая развивалась от версии к версии, добавляя / удаляя поля. Для обратной совместимости все версии хранятся в коде, что приводит к примерно следующему:

struct MyDataV0{
    int a;
    .....
};
struct MyDataV1{
    //int a disappeared for this version
    double d; //this fields was added to this version
    .....
};

Я хочу предоставить унифицированное представление этой структуры, которая является версией c. Есть ли для этого шаблон или передовой опыт?

Ответы [ 2 ]

0 голосов
/ 04 августа 2020

Это может не обеспечивать «унифицированное представление», типичный подход к обработке нескольких версий - с пространством имен:

namespace my_data
{
    namespace v1
    {
        // v1
        struct MyData { … };
    }
    inline namespace v2
    {
        // v2
        struct MyData { … };
    }
}

// To use v2
my_data::MyData data = {};
// or
my_data::v2::MyData data1 = {};

// To use v1
my_data::v1::MyData data2 = {};

По умолчанию вы будете использовать версию структуры, которая находится во встроенном пространстве имен , если вы хотите сослаться на более старую (возможно, устаревшую) версию, вам нужно будет указать ее явно. Затем вы можете перегрузить любую функцию, которая потребляет MyData, в том же пространстве имен, что и структура, и полагаться на ADL , чтобы найти правильную перегрузку.

0 голосов
/ 04 августа 2020

Вы также можете поближе познакомиться с созданием гибкого контейнера, например, в C ++ 17 вы можете использовать std::map со значениями std::variant. Единое определение и версия-агности c.

#include <string>
#include <map>
#include <iostream>
#include <variant>


int main()
{
    std::map<std::string, std::variant<int, double, std::string>> st;

    st["version"] = 2;
    st["field_int_v1"] = 1;
    st["field_double_v2"] = 1.1;  // added in version 2
    st["field_string_v2"] = "1.1 in text";

    //..
    // process somewhere
    std::cout << std::get<int>(st["field_int_v1"] ) << std::endl;
    if (std::get<int>(st["version"]) == 2){
        std::cout << std::get<double>(st["field_double_v2"] ) << std::endl;
        std::cout << std::get<std::string>(st["field_string_v2"]) << std::endl;
    }
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...