unified view to slightly different structs

Viewed 96

I have a complicated structs that evolved from version to version, adding/removing fields. For backward compatibility, all the versions are kept in the code, leading to something like this :

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

I want to provide a unified view of this struct that is version agnostic. Is there a pattern or best practices to do this?

2 Answers

You can also take a closer look at creating a flexible container, for example, in C++ 17 you can use std::map with std::variant values. Its definition is unified and version-agnostic.

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

This may not provide a 'unified view', the typical approach to handling multiple versions is with namespacing:

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 = {};

By default, you will use the version of the struct which is in the inline namespace, if you want to reference an older (possibly deprecated) version, you will have to be explicit. You can then overload any function which consumes MyData, in the same namespace as the struct and rely on ADL to find the correct overload.

Related