How to register a dynamic member in C++

Viewed 181

Magic methods in python are really magical. For example:

class DynMember:

    def __getattr__(self, name: str):
        def fn(self, **kwargs):
            print(kwargs)

        setattr(self.__class__, name, fn)

        return lambda **x: fn(self, **x)

if __name__ == "__main__":
    d = DynMember()
    d.someFn(title="Greeting", description="Hello world!") # outputs {'title': 'Greeting', 'description': 'Hello world!'}
    d.someFn(k1="value 1", k2="value 2") # outputs {'k1': 'value 1', 'k2': 'value 2'}

There was no someFn in DynMember class. The method is set on the class using __getattr__ magic method and setattr builtin method. These methods are really powerful and make classes do wonders in python. (have written a html generator only in 40 lines of code). How to achieve something similar in C++?

3 Answers

What you want is not supported by C++ yet, there is some third-party libraries like Qt or Boost which provide that. But (is ambiguity about what you exactly want) if you want to implement something like def fn(self, **kwargs) you can do it with Variadic Functions (Example) or Template Parameter Pack (Example) or Designated initializers from C++20 or std::map (as @alterigel mentioned on commnets).


Reflection:


KWArgs:

Yes and no. The question whether C++ support this or not is ambiguous. You can definitely create a new function on the fly - it is possible. There are two options:

  1. Load machine code into memory or
  2. Compile and load code at runtime.

But would you do it ? Probably not.

The main problem is that you are comparing an interpreted language with a compiled language. A compiled language needs compilation, while an interpreted language does not.

Obviously it is way easier to refer to a piece of code within the same VM than to compile and load. So because it is impractical I would say it is possible but not convenient.


See more:
Is it possible to create a function dynamically, during runtime in C++?

As mentioned elsewhere C++ doesn't support this yet. The best alternative that I can think would be to add a container to the class either publicly available or accessible through accessor functions. The container could be a map, mapping a string to a stored pointer to void. The user would then be responsible for knowing what type is stored in the pointer to void.

Here's one option of how to store it: std::map<std:string, void *> storedProperties;

Related