0

It's easy to do something like that in Python, but implementing it in C++ seems to be more challenging.

I actually have some solution to this, but I'd like to see if you can see any better solution.

Here's what I want to do.

I have a list of values of different types (string, integer, can be also instance of some class etc.). Now here's the first problem - in C++ (unlike in Python) all values in vector/array have to be of the same type.

The solution I can see is that I can use std::any like this: vector<std::any> list.

I also have an array/vector of functions (or pointers to functions) with different parameter types and returned values - one function can accept string and integer and return a char and other can accept a char and return an int. Here's another problem: in C++ you can have an array/vector of functions only if they have the same parameters and returned values (as far as I know) because in your declaration of the vector you need to define the parameter types and the returned value.

The other problem is that I need to retrieve the information about the parameters and the returned value for each function. In other words, having those functions, I need to know that this function accepts 2 strings and 1 integer and returns a char for example. In Python I can use inspect.signature function to retrieve information about type annotations of a function. In C++, I don't know if there is a way to do this.

The solution I can see here is to use std::any again (although I will use another solution, I will explain why later).

The solution I can see to this problem is that I won't retrieve that information but instead the user of the class which accepts this vector of functions will simply have to specify what are the parameter types and returned value for each function. In other words, the solution I can see is that I won't be retrieving the information about parameter types programmatically.

The other problem I have is that later I need to call one of those functions with some parameters. In Python I do this like this:

arguments = [1, 'str', some_object] // here I prepare a list of arguments (they are of different types)
func(**arguments)

In C++ I can do unpacking as well, but not if the parameters are of different types.

The solution I can see here is as follows. Those functions in the vector will all accepts only argument which is vector<std::any> args which will simply contain all of the arguments. Later when I want to call the function, I will simply construct a vector with std::any values and pass it as an argument. This would also solve the previous problem of not being able to store vector of functions with different parameters.

Can you see better solutions?

You might wonder what I need all of this is for. I do some program synthesis stuff and I need to programmatically construct programs from existing functions. I'm writing a library and I want the user of my library to be able to specify those base functions out of which I construct programs. In order to do what I want, I need to know what are the parameters and returned values of those functions and I need to call them later.

8
  • 6
    You are trying to use reflection (inspecting type information at run time). C++ doesn't have that - all type information is only available at compile time. You cannot take your Python solution (which appears to rely on reflection heavily) and translate it to C++ one-for-one. You need to start with the original problem you are trying to solve, and come up with a C++ solution for it. Now, what is the original problem you are trying to solve? Can you describe it without references to Python? As written, your question looks like an XY problem Commented Aug 2, 2020 at 13:32
  • 4
    Also, do not use other languages as a model in writing C++ code. If you go down that road, the code will either have bugs, be inefficient, or just plain look weird to a C++ programmer. Commented Aug 2, 2020 at 13:36
  • 1
    WHat happens if you call function with wrong parameter list? Also your python code essentially gives one level of suggestion: you need some kind of closure object to wrap arguments (list of arguments in Python is an object of sorts). If at time of calling function all proper arguments for that particular array element would already exist, you can be content with use of lambdas or their equivalents Commented Aug 2, 2020 at 13:41
  • 5
    C++ is not Python. Attempting to translate the same logic from Python to C++ is doomed to failure. In weakly-typed Python, lists may contain a hodge-podge of anything. C++ is strongly typed. Whatever problem weakly-typed Python lists were trying to solve, in C++ a different approach will be needed. Commented Aug 2, 2020 at 13:51
  • 3
    Oh, and this. Avoid std::variant and std::any like the plague. They have their place, but you as a new C++ programmer should strive to be far, far away from that place. This is my personal, highly subjective opinion. Commented Aug 2, 2020 at 14:31

2 Answers 2

2

I believe what you are looking for is std::apply. You can use std::tuple instead of std::vector to store a list of values of different types -- as long as the types are known at compile-time. Then std::apply(f, t) in C++ is basically the same as f(*t) in Python.

Sign up to request clarification or add additional context in comments.

Comments

0

I have a list of values of different types (string, integer, can be also instance of some class etc.).

A type which is a union of subtypes is called a sum type or tagged union. C++ has the template std::variant for that.

Now here's the first problem - in C++ (unlike in Python) all values in vector/array have to be of the same type.

Of course, so use cleverly C++ containers. You might want some std::map or std::vector of your particular instance of std::variant.

I also have an array/vector of functions

You probably want some std::vector of std::function-s and code with C++ lambda expressions

You should read a good C++ programming book

I'm writing a library and I want the user of my library to be able to specify those base functions out of which I construct programs.

You could get inspiration from SWIG and consider generating some C++ code in your library. So write (in Python or C++) your C++ metaprogram (generating some C++ code, like ANTLR does) which generates the user code, and your user would adapt his build automation tool for such a need (like users of GNU bison do).

You might also consider embedding Guile (or Lua) in your application.

PS. You might be interested by other programming languages like Ocaml, Go, Scheme (with Guile, and read SICP), Common Lisp (with SBCL), or Rust.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.