-1

I have a computational graph g that takes a certain number of "Variable" parameters (defined at runtime) I want to be able to use this graph like a function like :

auto a = g(x, y);

but that's not possible as the number of parameters is defined at runtime I would have to change the function so it accepts a vector of Variable instead and maybe do something like :

auto a = g({x, y});

but that's not very user friendly so I thought I could overload an operator of Variable so it automatically make a list and use it like :

auto a = g(x + y); 
//or
auto a = g(x ^ y); 
//or
auto a = g(x && y);

but that would be even more confusing. then I found that there is a comma operator that can be overloaded

auto a = g(x, y);

EDIT 1

attempt to a clearer explanation : g() could take a variable number of parameters but this number is only defined at runtime (the parameters are all of type "Variable") that is impossible in C++, that's why I want to "simulate" it : g() will actually take a vector of "Variable" as input and I want to overload the comma operator so that it packs the "Variable" into a vector

EDIT 2

I found an example of that in Boost.Assign :

vector<int> v; 
v += 1,2,3,4,5,6,7,8,9;

the commas are overloaded so that this works like {1,2,3,4,5,6,7,8,9}

EDIT 3

I tried to implement it and it doesn't work like I wanted because of the priority of operators : you have to write

auto a = g( (A, B, C) );

otherwise you get a compiler error : too many parameters

/EDIT

that seems too good to be true, before I start trying to implement it, is that even possible in the first place ? it seems a bit "hacky" is that a good practice ? or is there a way better alternative ?

I saw other methods that do that kind of thing but they are usually 10 times more complex using variadic templates and boost::any...

RedSkidy
  • 1
  • 3
  • 1
    Maybe you schould use `std::initializer_list` – 21koizyd Jul 02 '17 at 23:35
  • wouldn't that be the first version ? auto a = g({x, y}); – RedSkidy Jul 02 '17 at 23:36
  • 1
    What's the problem with a variadic template approach again? How is that not working out? If `g` is a function which takes `Args...` and returns a `Graph`, it's all fine, no? – DeiDei Jul 02 '17 at 23:37
  • @RedSkidy you can use overloading constructor or function (whatever is g()) or metaprogramming. Yea it's some like vector. Can you define better problem? – 21koizyd Jul 02 '17 at 23:38
  • I haven't really used variadic templates yet, do they work even when the number of argument the function will take is defined at runtime ? – RedSkidy Jul 02 '17 at 23:39
  • @21koizyd the problem is that the function could be : g(x, y) or g(x, y, z) or g(a, b, c, d, e, f)... I don't know and the number of parameters isn't know at compile time – RedSkidy Jul 02 '17 at 23:40
  • specialization templates i think will be good option. – 21koizyd Jul 02 '17 at 23:41
  • Variadic template arguments will work for this. – David G Jul 02 '17 at 23:41
  • 1
    The thing is, you haven't provided enough code/information for us to propose a solution. – DeiDei Jul 02 '17 at 23:42
  • @RedSkidy DeiDei have right with number elements. But templates type will be deduced in compile time, so good option will be make specialization templates – 21koizyd Jul 02 '17 at 23:43
  • I don't understand how variadic templates could work in that case. variadic templates generate multiple versions of the same function with different parameters right ? if the compiler knows the 1-param-version and the 3-param-version will be used, it compiles both versions but if this number is only known at runtime ? the user could decide the function takes 300 parameters... does it generate like a thousand versions of the same functions ? – RedSkidy Jul 02 '17 at 23:45
  • @RedSkidy maybe you schould pack your variable before give them to function? f.e to vector or something like that? – 21koizyd Jul 02 '17 at 23:45
  • @21koizyd that's what i want the comma overload to do : auto x = a, b; //x will be a vector of Variable – RedSkidy Jul 02 '17 at 23:46
  • `std::vector` it's only solution which i have :D – 21koizyd Jul 02 '17 at 23:48
  • 1
    @RedSkidy It's impossible to generate a function call with parameters decided during runtime. C++ is not an interpreted language. I don't understand your confusion. The program either calls a function with some arguments, or it doesn't. The compiler will generate the necessary functions after the variadic template is instantiated appropriately. – DeiDei Jul 02 '17 at 23:48
  • that's why I want to use this comma operator hack to simulate a dynamic function, it will look like a function but there is actually only one argument : a vector of Variable, the comma operator is overloaded so that it packs the variables together – RedSkidy Jul 02 '17 at 23:51
  • How exactly are the number of parameters decided at runtime? In the example you've shown `auto a = g(x, y);`, is that how you will call the function in your source code? Where's the runtime factor there? You've clearly passed 2 arguments, and the compiler will see that. Or are you wanting to pass that as a string value? Something like `execute_string("auto a = g(x, y);");` – Benjamin Lindley Jul 03 '17 at 00:19
  • I have a computational graph that takes a certain number of "Variable" as input. these graphs will define what computation will be applied to the Variables. for example : I have 3 variables : A, B and C. then I have a node that multiplies the values of 2 "Variable". I also have another node that adds 2 "Variable". I define my graph by doing something like : – RedSkidy Jul 03 '17 at 00:27
  • Variable A; Variable B; Variable C; auto t = multiply(A, B); auto O = add(t, C); O will be my output, I can then get the whole graph by calling : auto g = O.getGraph(); then I can use g like : float r = g(2.0, 3.0, 1.2);//r will be : 2.0*3.0+1.2 = 7.2 – RedSkidy Jul 03 '17 at 00:31

2 Answers2

0

If you want overloaded comma and get some undefined number parameters, so it's impossible, only way is in compile time with use metaprogramming.

You can try choose user what he want give (data) and use special method(for type data) and later add to std::vector<boost::any> v {a, b, c}

You can use std::vector<boost::any> if you want a lot of parameters and other types in one container, later give him to g()

You can see too enter link description here

how display elements from boost::any.

version in C++17

std::vector<std::experimental::fundamentals_v1::any> v {10, 5.5, "HEY", 4.4}

with boost library

std::vector<boost::any> v {1, 5.5, "HEY"}

It's impossible to generate a function call with parameters decided during runtime..... ~DeiDei (rest in comments)

21koizyd
  • 1,843
  • 12
  • 25
  • all my parameters will have the same type : "Variable" so there is no need to use boost::any (I think ?) and with a vector, wouldn't that be the first solution ? : auto a = g({x, y}); – RedSkidy Jul 02 '17 at 23:57
  • but you will get parameters in runtime, so probably boost::any will be can take paramater each type in runtime, I think. – 21koizyd Jul 03 '17 at 00:01
  • they all have the same type and the point of using this comma hack was to remove the {} – RedSkidy Jul 03 '17 at 00:09
  • it's impossible in c++ – 21koizyd Jul 03 '17 at 00:09
  • what is impossible ? – RedSkidy Jul 03 '17 at 00:11
  • you can try choose user what he want give (data) and use special method(for type data) and later add to `std::vector v {a, b, c}` – 21koizyd Jul 03 '17 at 00:11
  • @RedSkidy "It's impossible to generate a function call with parameters decided during runtime." ~DeiDei – 21koizyd Jul 03 '17 at 00:13
  • I know, that's why I thought about a way to simulate that, again : g(a, b, c, d) will actually behave like g(std::vector({a, b, c, d})); the comma operator will be overloaded so that it automatically packs the "Variable" objects together in a vector so g will actually be defined as : Variable g(std::vector v); – RedSkidy Jul 03 '17 at 00:20
  • why you want overloaded operator comma or maybe you will overloade operator comma and you don't know how? – 21koizyd Jul 03 '17 at 00:27
  • I want to overload the comma operator so that using my graph looks exactly like calling a function so it's easier for the user, I was just asking basically if this is a good idea or not – RedSkidy Jul 03 '17 at 00:35
  • If you want overloaded comma and get some undefined number parameters, so it's impossible, only way is in compile time with use metaprogramming, that's all – 21koizyd Jul 03 '17 at 00:35
  • why would it be impossible ? you can overload commas and using that method means there is always only one parameters to the function but it looks like there are many – RedSkidy Jul 03 '17 at 00:37
  • i think, that is impossible in runtime. Maybe someone smarter help you – 21koizyd Jul 03 '17 at 00:42
  • but you must know how many arguments you will have in runtime, because function will be execute in compile time – 21koizyd Jul 03 '17 at 00:45
  • 1 argument, always : a vector of "Variable", the function looks like it has multiple parameters because of the overloaded commas hack but actually it's just 1 parameter – RedSkidy Jul 03 '17 at 00:47
0

I am not so sure whether this is what you are trying to do but you could just make g a variadic template with a specialization for std::vector<Variable>. The variadic version simply packs the arguments in a vector and calls the specialization.

#include <iostream>
#include <vector>

using Variable = int;

template < typename ... Args >
int g(Args ... args)
{
  return g(std::vector<Variable>{args...});
}

template < >
int g(std::vector<Variable> v)
{
  // do something with v
  for (auto const& p : v)
    std::cout << p << '\n';
  return 0;
}


int main()
{
  auto a = g(1,2,3);
}
Henri Menke
  • 10,705
  • 1
  • 24
  • 42