Conditionally initialize a struct field - only if it exists in that struct - c++

Working on something like a unit testing framework for a very simple API:
extern "C" void execute_command(int cmd, void *params);
Which casts the params to the appropriate struct based on the cmd argument. I can't change that interface, nor can I modify the header which specifies the commands and the different param structures (which are all POD).
I do have access to an array of something like:
{ 0 /*cmd number*/, "PARAM_STRUCT_FOR_CMD_0", sizeof(PARAM_STRUCT_FOR_CMD_0) }
These param structs have some common properties. For example, many of them have a field like void *pObject;, though it is not always the same offset. To illustrate, suppose there are three structures:
struct {
void *pObject;
int someData;
} PARAM_STRUCT_FOR_CMD_0;
struct {
float someFloatData;
void *pObject;
} PARAM_STRUCT_FOR_CMD_1;
struct {
float someFloatData;
void *pAnotherObject;
} PARAM_STRUCT_FOR_CMD_2;
These two pObject fields represent the same thing, while pAnotherObject is unrelated.
Now, on to what I actually want: I'd like to cast a void* to some struct, based on cmd, and set its pObject field, if it exists in that struct. Ideally, I'd be able to do something like:
void *pGlobalObject;
void execcmd(int cmd)
{
static uint8_t params[MAX_SIZE_OF_PARAM_STRUCT];
memset(params, 0, MAX_SIZE_OF_PARAM_STRUCT);
INIT_STRUCT_IF_POSSIBLE(cmd, (void*)params);
execute_command(cmd, params);
}
Where INIT_STRUCT_IF_POSSIBLE could be something like:
#define INIT_STRUCT_IF_POSSIBLE(cmd, str) \
do { \
switch (cmd) \
{ \
case 0: static_cast<PARAM_STRUCT_FOR_CMD_0*>(str)->pObject = pGlobalObject; break; \
case 1: static_cast<PARAM_STRUCT_FOR_CMD_1*>(str)->pObject = pGlobalObject; break; \
case 2: /* nothing, no pObject field */ break; \
} \
} while (0)
except that isn't really scalable. I have ~1000 possible commands, and let's say 5 fields which I'd like to set (no struct has all 5), and new commands can be added, so I'd like to avoid manually changing this.
The obvious solution is an extra build step that parses all the structs, and creates their initializers. Adding this extra build step is a lot of pain though, due to how the project is structured, so I'm hoping for a pure C++ solution.
If there's a way to generate the initializers using the C preprocessor, I'm all for it. If it can somehow be done using templates, just as good. I have boost and C++11 available, if it helps.
One thing that would solve this is the designated initializers, such as STR x = {.pObject = pGlobalObject; };. Unfortunately, they cause an error when the field is not available. Any way to just ignore nonexistent fields? (Yes, I know they are C only, not C++, but I can switch to C if needed)

Welcome to the world of SFINAE
template<typename T>
typename std::enable_if<
std::is_same<decltype(T::pObject), void*>::value
>::type setPobject(T *t) {
t->pObject = pGlobalObject;
}
void setPobject(void *t) { }
template<typename T>
typename std::enable_if<
std::is_same<decltype(T::someFloatData), float>::value
>::type setSomeFloatData(T *t) {
t->someFloatData = someGlobalFloat;
}
void setSomeFloatData(void *t) { }
// ...
Just call them for all your objects with the correct types and they will figure out whether they apply or not themselfs. You can also automate the casting
template<typename D>
struct Call {
static void call(void *t) {
setPobject(static_cast<D*>(t));
setSomeFloatData(static_cast<D*>(t));
}
};
// desginated initializers here for convenience (non-C++)
void (* const table[])(void*) = {
[0] = Call<PARAM_STRUCT_FOR_CMD_0>::call,
[1] = Call<PARAM_STRUCT_FOR_CMD_1>::call
// ...
};

With some SFINAE you can detect the member and (type) dispatch assignment accordingly:
#include <iostream>
#include <type_traits>
// Member variable detection
// =========================
template<typename T, typename = void>
struct has_pObject : std::false_type { };
template<typename T>
struct has_pObject<T, decltype(std::declval<T>().pObject, void())> : std::true_type { };
// Optional member variable assignment
// ===================================
namespace Detail
{
template <typename T>
void assign_pObject(T& object, void* p, std::false_type) {}
template <typename T>
void assign_pObject(T& object, void* p, std::true_type) {
object.pObject = p;
}
}
template <typename T>
void assign_pObject(T& object, void* p) {
Detail::assign_pObject(object, p, has_pObject<T>());
}
// Test
// ====
struct {
void *pObject = nullptr;
int someData = 0;
} PARAM_STRUCT_FOR_CMD_0;
struct {
float someFloatData = 0;
void *pObject = nullptr;
} PARAM_STRUCT_FOR_CMD_1;
struct {
float someFloatData = 0;
void *pAnotherObject = nullptr;
} PARAM_STRUCT_FOR_CMD_2;
int main()
{
int object;
assign_pObject(PARAM_STRUCT_FOR_CMD_0, &object);
assign_pObject(PARAM_STRUCT_FOR_CMD_1, &object);
assign_pObject(PARAM_STRUCT_FOR_CMD_2, &object);
std::cout << PARAM_STRUCT_FOR_CMD_0.pObject << '\n';
std::cout << PARAM_STRUCT_FOR_CMD_1.pObject << '\n';
std::cout << PARAM_STRUCT_FOR_CMD_2.pAnotherObject << '\n';
return 0;
}

Related

Usage of empty structs in C++

In some code that I was reading, I found the usage of empty struct like so:
struct input_iterator_tag { };
struct bidirectional_iterator_tag { };
struct random_access_iterator_tag { };
So in the rest of the code, it was used as what they call tag dispatching.
I was wondering if there is other usage of empty structs.
from an older post I saw that :
three major reasons we use empty structs in C++ are:
a base interface
a template parameter
a type to help overload resolution. (tag dispatching if I am not wrong)
Could someone explain that please?
a type to help overload resolution. (tag dispatching if I am not wrong)
When you want to use a complex template specialization pattern on some function, you don't try to go at it directly, but rather write:
template <typename T1, typename T2, other things maybe>
int foo(T1 param1, T2 param2 and so on)
{
using tag = put your complex stuff here, which produces an empty struct
detail::foo_impl(tag, std::forward<T1>(param1), std::forward<T2>(param2) and so on);
}
Now, the compiler doesn't have to decide between competing choices of template specialization, since with different tags you get incompatible functions.
a base interface
struct vehicle {
// common members and methods,
// including (pure) virtual ones, e.g.
virtual std::size_t num_maximum_occupants() = 0;
virtual ~vehicle() = default;
};
namespace mixins {
struct named { std::string name; };
struct wheeled { int num_wheels; public: rev() { }; };
} // namespace mixins
struct private_sedan : public vehicle, public wheeled, named {
// I dunno, put some car stuff here
//
// and also an override of `num_maximum_occupants()`
};
Making the base struct completely empty is perhaps not that common, but it's certainly possible if you use mixins a lot. And you could check for inheritance from vehicle (although I'm not sure I'd do that).
a template parameter
Not sure what this means, but venturing a guess:
template <typename T>
struct foo { };
template <typename T, typename N>
struct foo<std::array<T, N>> {
int value = 1;
};
If you now use foo<T>::value in a function, it will work only if T is int with few (?) exceptions.
I also tried to come up with examples:
as a base interface
// collection of very abstract vehicles
#include <vector>
struct Vehicle {};
struct Car : Vehicle {
int count_of_windows;
};
struct Bike : Vehicle {
int size_of_wheels;
};
std::vector<Vehicle> v{Bike{}, Car{}};
as a template parameter
// print same number in 3 different formats
#include <iostream>
struct dec {};
struct hex {};
struct octal {};
template<typename HOW = dec>
void print_me(int v);
template<>
void print_me<dec>(int v) {
auto f = std::cout.flags();
std::cout << std::dec << v << std::endl;
std::cout.flags(f);
}
template<>
void print_me<hex>(int v) {
auto f = std::cout.flags();
std::cout << std::hex << v << std::endl;
std::cout.flags( f );
}
template<>
void print_me<octal>(int v) {
auto f = std::cout.flags();
std::cout << std::oct << v << std::endl;
std::cout.flags(f);
}
int main() {
print_me(100);
print_me<hex>(100);
print_me<octal>(100);
}
a type to help overload resolution
// add a "noexcept" qualifier to overloaded function
// the noexcept version typically uses different functions
// and a custom "abort" handler
#include <iostream>
struct disable_exceptions {};
void is_number_1() {
int v;
std::cin >> v;
if (v != 1) {
throw new std::runtime_error("AAAA");
}
}
void is_number_1(disable_exceptions) noexcept {
int v;
// use C function - they don't throw
if (std::scanf("%d", &v) != 1) {
std::abort();
}
if (v != 1) {
std::abort();
}
}
int main() {
is_number_1();
is_number_1(disable_exceptions());
}
The example about "tag dispatching" can be found on cppreference iterator_tags. The iterator_category() member of an iterator is used to pick a different overload. That way you could write a different algorithm if for example iterator is forward_iterator, where you can only go forward, or it is a bidirectional_iterator, where your algorithm could change because you may walk back.

tag dispatching for inherited classes

I have some code where I have a base class (lets call it foo) that has a variable number of derived classes (between 10-500) created by a generation script. Currently we have a function that will create a new base class by passing in its name as a string and then using a giant if/else statement to find the right one.
for example
if (name == "P2_26") {add_module(new P2_26());}
else if (name == "P4_30") {add_module(new P4_30());}
...
This leads to a giant if else block. This seems to me like code that could be simplified by using tag dispatching, but every example I find online uses built-ins like iterators that already have tags defined and I could not interpolate to my use case. Is there anyway to streamline this code?
Tag dispatched is based on type information as an input. Judging from your code you have a string as an input which which can not be used in run time.
Your case looks more like an abstract factory:
// Factory.h
class Base;
struct Factory {
using spawn_t = std::function<Base*()>;
using container_t = std::unordered_map<std::string, spawn_t>;
static container_t& producers() {
// This way it will be initialized before first use
static container_t producers;
return producers;
}
static Base* spawn(const std::string& name) {
auto it = producers().find(name);
if (it == producers().end()) return nullptr;
return it->second();
}
};
// Base.h
#define STR(x) #x
#define DEFINE_REGISTRATOR(_class_) \
DerivedRegistrator<_class_> _class_::_sRegistrator_(STR(_class_))
#define DECLARE_REGISTRATOR(_class_) \
static DerivedRegistrator<_class_> _sRegistrator_
template<typename T>
struct DerivedRegistrator{
DerivedRegistrator(const std::string& name) {
Factory::producers()[name] = [](){ return new T(); };
}
};
class Base {
// ...
};
And then generated files should include:
// Derived1.h
class Derived1 : public Base {
DECLARE_REGISTRATOR(Derived1);
// ...
};
// Derived1.cpp
DEFINE_REGISTRATOR(Derived1); // Will register automatically
This solution will register all classes automatically on program start which is more like what you had before.
UPD.
To use it you can simply replace all your if-else code with this line:
add_module(Factory::spawn(name));
Or if you can't handle nullptr in add_module:
Base* ptr = Factory::spawn(name);
if (ptr) {
add_module(ptr);
}
Thanks to D Drmmr for making this code better.
template<class T>
struct named_factory {
const char* name;
std::function<std::unique_ptr<T>()> factory;
};
struct find_factory {
using is_transparent=std::true_type;
struct named {
const char* str;
template<class T>
named(named_factory<T> const& f):str(f.name) {}
named(const char* name):str(name) {}
};
bool operator()(named lhs, named rhs) {
return strcmp(lhs.str, rhs.str)<0;
}
};
#define MAKE_STR2(X) #X
#define MAKE_STR(X) MAKE_STR2(X)
#define FACTORY(X,...) \
named_factory<__VA_ARGS__>{\
MAKE_STR(X),\
[]{\
return std::make_unique<X>()\
}\
}
Now we can:
std::set<named_factory<foo>, find_factory> factories = {
FACTORY(P2_26, foo),
FACTORY(P4_30, foo),
// ...
};
and in code you do:
bool add_module_by_name( const char* name ) {
auto it = factories.find(name);
if (it == factories.end()) return false;
auto module = it->factory();
if (!module) return false;
add_module( module.release() );
return true;
}
This is a data-driven design. The search for the right type is done in logarithmic time, not linear like your code. You could probably replace it with an unordered_map instead of a set.
However, if your type names are determined at compile time, you can do better. (Ie, if you have a hard coded "P2_26" at the call site).
template<class T>
struct tag_t { using type=T; constexpr tag_t(){} };
template<class T>
constexpr tag_t<T> tag{};
template<class T>
void add_module( tag_t<T> ) {
// ...
add_module( new T() );
}
Now you can add_module(tag<P2_26>) and skip the long if/else statement.
We can even hide the implementation of the outer add_module via this:
// in cpp file:
void add_module_impl( std::function< std::unique_ptr<foo>() > maker ) {
// ...
add_module( maker().release() );
}
// in h file:
void add_module_impl( std::function< std::unique_ptr<foo>() > maker );
template<class T>
void add_module( tag_t<T> t ) {
add_module_impl([]{ return std::make_unique<T>(); });
}
and again, we can add_module(tag<P4_30>) and it just works.

C++ auto deduction of return type

I want to write a function that return different types based on different input as below.
enum MyType
{
A,
B
};
template<MyType T> struct MyStruct
{
};
static auto createMyStruct(MyType t)
{
if(t==A)
return MyStruct<A>();
else
return MyStruct<B>();
}
It didn't work out because there are two return types for one auto. Is there any other way to do this?
There is absolutely no way of having a (single) function that returns different types based on a runtime decision. The return type has to be known at compile time. However, you can use a template function, like this (thanks to #dyp for making me simplify the code):
#include <iostream>
#include <typeinfo>
enum MyType
{
A,
B
};
template<MyType>
struct MyStruct {};
template<MyType type>
MyStruct<type> createMyStruct()
{
return {};
}
int main()
{
auto structA = createMyStruct<A>();
auto structB = createMyStruct<B>();
std::cout << typeid(structA).name() << std::endl;
std::cout << typeid(structB).name() << std::endl;
}
I am assuming you want to write code like this:
void foo (MyType t) {
auto x = createMyStruct(t);
//... do something with x
}
You are attempting to derive the right type for x at runtime. However, the return type of a function must be known at compile time, and the type resolution for auto is also determined at compile time.
You could instead restructure your code to be like this:
template<MyType T> struct MyStruct
{
//...
static void foo () {
MyStruct x;
//... do something with x
}
};
The idea is to write a single foo() function whose only difference is the type of thing it is manipulating. This function is encapsulated within the type itself. You can now make a runtime decision if you have a mapping between MyType and MyStruct<MyType>::foo.
typedef std::map<MyType, void(*)()> MyMap;
template <MyType...> struct PopulateMyMap;
template <MyType T> struct PopulateMyMap<T> {
void operator () (MyMap &m) {
m[T] = MyStruct<T>::foo;
}
};
template <MyType T, MyType... Rest> struct PopulateMyMap<T, Rest...> {
void operator () (MyMap &m) {
m[T] = MyStruct<T>::foo;
PopulateMyMap<Rest...>()(m);
}
};
template<MyType... Types> void populateMyMap (MyMap &m) {
PopulateMyMap<Types...>()(m);
}
//...
populateMyMap<A, B>(myMapInstance);
Then, to make a runtime decision:
void foo (MyType t) {
myMapInstance.at(t)();
}
I think you should learn abstract factory design pattern.
For use objects of type MyStruct<A> or MyStruct<B> you need common interface.
Common interface provided in abstract base class.
struct MyStruct
{
virtual ~MyStruct() {}
virtual void StructMethod() = 0;
};
struct MyStructA: public MyStruct
{
void StructMethod() override {}
};
struct MyStructB: public MyStruct
{
void StructMethod() override {}
};
std::unique_ptr<MyStruct> createMyStruct(MyType t)
{
if (t==A)
return std::make_unique<MyStructA>();
else
return std::make_unique<MyStructB>();
}

Dynamically define a function return type

I have a Message class that is able to pack its payload to binary and unpack it back. Like:
PayloadA p;
msg->Unpack(&p);
where PayloadA is a class.
The problem is that I have a bunch of payloads, so I need giant if or switch statement:
if (msg->PayloadType() == kPayloadTypeA)
{
PayloadA p;
msg->Unpack(&p); // void Unpack(IPayload *);
// do something with payload ...
}
else if ...
I want to write a helper function that unpacks payloads. But what would be the type of this function? Something like:
PayloadType UnpackPayload(IMessage *msg) { ... }
where PayloadType is a typedef of a proper payload class. I know it is impossible but I looking for solutions like this. Any ideas?
Thanks.
I would split one level higher to avoid the problem entirely:
#include <map>
#include <functional>
...
std::map<int, std::function<void()> _actions;
...
// In some init section
_actions[kPayloadA] = [](IMessage* msg) {
PayloadA p;
msg->Unpack(&p);
// do something with payload ...
};
// repeat for all payloads
...
// decoding function
DecodeMsg(IMessage* msg) {
_actions[id](msg);
}
To further reduce the code size, try to make Unpack a function template (possible easily only if it's not virtual, if it is you can try to add one level of indirection so that it isn't ;):
class Message {
template <class Payload>
Payload Unpack() { ... }
};
auto p = msg->Unpack<PayloadA>();
// do something with payload ...
EDIT
Now let's see how we can avoid writing the long list of _actions[kPayloadN]. This is highly non trivial.
First you need a helper to run code during the static initialization (i.e. before main):
template <class T>
class Registrable
{
struct Registrar
{
Registrar()
{
T::Init();
}
};
static Registrar R;
template <Registrar& r>
struct Force{ };
static Force<R> F; // Required to force all compilers to instantiate R
// it won't be done without this
};
template <class T>
typename Registrable<T>::Registrar Registrable<T>::R;
Now we need to define our actual registration logic:
typedef map<int, function<void()> PayloadActionsT;
inline PayloadActionsT& GetActions() // you may move this to a CPP
{
static PayloadActionsT all;
return all;
}
Then we factor in the parsing code:
template <class Payload>
struct BasePayload : Registrable<BasePayload>
{
static void Init()
{
GetActions()[Payload::Id] = [](IMessage* msg) {
auto p = msg->Unpack<Payload>();
p.Action();
}
}
};
Then we define all the payloads one by one
struct PayloadA : BasePayload<PayloadA>
{
static const int Id = /* something unique */;
void Action()
{ /* what to do with this payload */ }
}
Finally we parse the incoming messages:
void DecodeMessage(IMessage* msg)
{
static const auto& actions = GetActions();
actions[msg->GetPayloadType]();
}
How about a Factory Method that creates a payload according to the type, combined with a payload constructor for each payload type, taking a message as a parameter?
There's no avoiding the switch (or some similar construct), but at least it's straightforward and the construction code is separate from the switch.
Example:
class PayloadA : public Payload
{
public:
PayloadA(const &Message m) {...} // unpacks from m
};
class PayloadB : public Payload
{
public:
PayloadB(const &Message m) {...} // as above
};
Payload * UnpackFromMessage(const Message &m)
{
switch (m.PayloadType) :
case TypeA : return new PayloadA(m);
case TypeB : return new PayloadB(m);
... etc...
}
I seen this solved with unions. The first member of the union is the type of packet contained.
Examples here: What is a union?
An important question is how the payloads differ, and how they are the same. A system whereby you produce objects of a type determined by the payload, then interact with them via a virtual interface that is common to all types of payload, is reasonable in some cases.
Another option assuming you have a finite and fixed list of types of payload, returning a boost::variant is relatively easy. Then to process it, call apply_visitor with a functor that accepts every type in the variant.
If you only want to handle one type of payload differently, a "call and run the lambda if and only if the type matches T" function isn't that hard to write this way.
So you can get syntax like this:
struct State;
struct HandlePayload
{
typedef void return_type;
State* s;
HandlePayload(State* s_):s(s_) {}
void operator()( int const& payload ) const {
// handle int here
}
void operator()( std::shared_ptr<bob> const& payload ) const {
// handle bob ptrs here
}
template<typename T>
void operator()( T const& payload ) const {
// other types, maybe ignore them
}
}
which is cute and all, but you'll note it is quite indirect. However, you'll also note that you can write template code with a generic type T above to handle the payload, and use stuff like traits classes for some situations, or explicit specialization for others.
If you expect the payload to be one particular kind, and only want to do some special work in that case, writing a single-type handler on a boost::variant is easy.
template<typename T, typename Func>
struct Helper {
typedef bool return_type;
Func f;
Helper(Func f_):f(f_) {}
bool operator()(T const& t) {f(t); return true; }
template<typename U>
bool operator()(U const& u) { return false; }
};
template<typename T, typename Variant, typename Func>
bool ApplyFunc( Variant const& v, Func f )
{
return boost::apply_visitor( Helper<T, Func>(f), v );
}
which will call f on a variant v but only on the type T in the Variant, returning true iff the type is matched.
Using this, you can do stuff like:
boost::variant<int, double> v = 1.0;
boost::variant<int, double> v2 = int(1);
ApplyFunc<double>( v, [&](double d) { std::cout << "Double is " << d << "\n"; } );
ApplyFunc<double>( v2, [&](double d) { std::cout << "code is not run\n"; } );
ApplyFunc<int>( v2, [&](int i) { std::cout << "code is run\n"; } );
or some such variant.
One good solution is a common base class + all payloads inheriting from that class:
class PayLoadBase {
virtual char get_ch(int i) const=0;
virtual int num_chs() const=0;
};
And then the unpack would look like this:
class Unpacker {
public:
PayLoadBase &Unpack(IMessage *msg) {
switch(msg->PayLoadType()) {
case A: a = *msg; return a;
case B: b = *msg; return b;
...
}
}
private:
PayLoadA a;
PayLoadB b;
PayLoadC c;
};
You can make the function return a void *. A void pointer can be cast to any other type.

Design Pattern, adding data to a class (3rd party) without modifying it

When I have to extend the behaviour of a class without modifying it, I often use the design pattern visitor. It adds member-like functions without modifying the core of the class it works with.
More or less in the same way, I need to extend a third party class, but mostly with data, not behaviour.
In such cases, I often use a std::map matching the a key MyClass* with a value MyClassExtender. MyClassExtender contains all the additionnal information.
While doing that, I happened to wonder if there are other ways of doing that, maybe more common or more 'best-practice". Should I call this additive class an Extender ?
Is there a name for such a pattern...
Nota Bene: I could have simply aggregated the MyClass* and MyClassExtender in a new class, but I need to access MyClassExtender given a MyClass* really often, so the st::map is really convinient.
Why don't you just subclass the class? Inheritance is the way to extend classes, whether with behavior or state. Unless you just want to associate instances of the class with other data, in which case it's not extending at all, and a std::map is the right answer.
So - create your MyClass object with in the struct with your extension objects:
struct MyClassEx {
MyClassExtension extension;
MyClass object;
};
To make it more robustness for different types - use templates from the example: http://ideone.com/mmfK83
The solution below is inspired by std::shared_ptr/std::make_shared:
template <typename Type>
struct LinkExtension;
template <typename Type>
struct TypeEx {
using Extension = typename LinkExtension<Type>::Type;
alignas(Type) uint8_t objectData[sizeof(Type)];
alignas(Extension) uint8_t extensionData[sizeof(Extension)];
Type* getObject() { return reinterpret_cast<Type*>(objectData); }
const Type* getObject() const { return reinterpret_cast<const Type*>(objectData); }
Extension* getExtension() { return reinterpret_cast<Extension*>(extensionData); }
const Extension* getExtension() const { return reinterpret_cast<const Extension*>(extensionData); }
template <class... Args>
TypeEx(Args&&... args)
{
new (objectData) Type(std::forward<Args>(args)...);
new (extensionData) Extension();
}
~TypeEx()
{
getObject()->~Type();
getExtension()->~Extension();
}
TypeEx(const TypeEx&) = delete;
TypeEx& operator = (const TypeEx&) = delete;
};
And some helper functions:
template <typename Type, class... Args>
Type* createObjectEx(Args&&... args)
{
TypeEx<Type>* retVal = new TypeEx<Type>(std::forward<Args>(args)...);
return retVal->getObject();
}
template <typename Type>
typename LinkExtension<Type>::Type& getObjectEx(Type* obj)
{
static_assert(std::is_standard_layout<TypeEx<Type>>::value, "Oops");
static_assert(offsetof(TypeEx<Type>, objectData) == 0, "Oops");
TypeEx<Type>* retVal = static_cast<TypeEx<Type>*>((void*)obj);
return *(retVal->getExtension());
}
template <typename Type>
const typename LinkExtension<Type>::Type& getObjectEx(const Type* obj)
{
static_assert(std::is_standard_layout<TypeEx<Type>>::value, "Oops");
static_assert(offsetof(TypeEx<Type>, objectData) == 0, "Oops");
const TypeEx<Type>* retVal = static_cast<const TypeEx<Type>*>((const void*)obj);
return *(retVal->getExtension());
}
template <typename Type>
void deleteObjectEx(const Type* obj)
{
const TypeEx<Type>* objectEx = static_cast<const TypeEx<Type>*>((const void*)obj);
delete objectEx;
}
And how to link extension to class:
class MyClass {
public:
virtual ~MyClass() = default;
};
struct MyClassExtension {
int a;
int b;
};
template <>
struct LinkExtension<MyClass> {
using Type = MyClassExtension;
};
And proof it works:
void printExtension(MyClass* object);
int main() {
MyClass* object = createObjectEx<MyClass>();
MyClassExtension& extension = getObjectEx(object);
extension.a = 1;
extension.b = 2;
printExtension(object);
deleteObjectEx(object);
TypeEx<MyClass> objectEx;
objectEx.getExtension()->a = 3;
objectEx.getExtension()->b = 4;
printExtension(objectEx.getObject());
}
void printExtension(MyClass* object)
{
MyClassExtension& extension = getObjectEx(object);
std::cout << extension.a << ' ' << extension.b << std::endl;
}
If your compiler does not support variadic templates, the solution is still possible, but requires more hand work to be complete.