4

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++?

pouya
  • 3,400
  • 6
  • 38
  • 53
  • It appears you're looking for reflection. C++ doesn't support this yet, but there are libraries that will let you do what you want. `Boost` likely has something that you could use. – cigien Dec 20 '20 at 21:07
  • 3
    It's not "magical" per se, there's just a lot of hidden machinery at runtime that makes this work. You can emulate this behaviour pretty closely with a `std::map` and some complex templates but it would be neither pretty nor efficient. C++ offers you lots of other tools and it's worth getting to know them well first before trying to apply them to a problem. Do you have a specific task you'd like to solve, and before you ask for free code, have you tried to solve it yourself? – alter_igel Dec 20 '20 at 21:14
  • practically sounds like you asking for a function pointer (or its wrappers, `std::function`, ect.). Or reflection? Or CRTP? It's not really clear what you want without true use case. A lot of Python functionality is actually functionality of huge number of libraries written in C and C++ underneath that interpreter, the ideology language itself is different. – Swift - Friday Pie Dec 20 '20 at 21:49

3 Answers3

5

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:

Ghasem Ramezani
  • 2,683
  • 1
  • 13
  • 32
  • Really don't know what part of the question is ambiguous. I have written a class in python and registered `someFn` in runtime and asked for the same in CPP. You mentioned `Qt`, haven't seen such a thing in Qt. It would be nice if you elaborate more cause I'm writing a `Qt/QML` app. Actually I searched around the topic and seems like the golden keyword is `metaprogramming` and many examples I have seen have used `templates` to make functions generic. I will search more around reflection. Thanks for providing the links but nothing replaces code:). – pouya Dec 21 '20 at 08:00
  • There is a lot of things: 1) *Variadic function*. 2) *Reflection*. 3)* Various initialization mode* . 4) ... . And `Qt` implemented reflection, take a look at `QObject`. Implementing reflection couldn't be done in 10-20 of lines so those links does the job better than codes. – Ghasem Ramezani Dec 21 '20 at 08:06
0

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++?

Ghasem Ramezani
  • 2,683
  • 1
  • 13
  • 32
Salvaterra
  • 21
  • 3
-1

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;

Jeff Spencer
  • 507
  • 2
  • 11