Вам нужны tagged union. Вот как это выглядело бы на Swift, например:
enum Foo {
case qqq(Int)
case www(Int)
}
let x = Foo.qqq(5)
let y = Foo.www(10)
На C++ это часто эмулируется с помощью наследования:
class Foo {
public:
virtual ~Foo() = 0;
};
class qqq : public Foo {
public:
int value;
explicit qqq(int value);
};
class www : public Foo {
public:
int value;
explicit www(int value);
};
using FooPtr = std::unique_ptr<Foo>;
FooPtr makeQqq(int value);
FooPtr makeWww(int value);
FooPtr x = makeQqq(5);
FooPtr y = makeWww(10);
Я опустил небольшое количество кода, который, я не сомневаюсь, вы могли бы сами закончить, если действительно хотите заставить этого монстра работать :)
Есть и более чистый способ: подключите либу
type_safe
(кликабельно).
#include <type_safe/strong_typedef.hpp>
#include <type_safe/variant.hpp>
namespace ts = type_safe;
using qqq = ts::strong_typedef<int>;
using www = ts::strong_typedef<int>;
using Foo = ts::variant<qqq, www>;
// ...
auto x = Foo(qqq(5));
auto y = Foo(www(10));
if (x.has_value(ts::variant_type<qqq>{})) {
qqq value = x.value(ts::variant_type<qqq>{}));
std::cout << "qqq" << ' ' << static_cast<int>(value);
}