Pass a variable number of arguments into a function - c++

I know how to use variadic templates and ellipses to accept a variable number of arguments, but how do you pass a variable number of arguments into a function?
Take the following code for example:
#include <iostream>
struct A {
A(int a, int b) : x(a), y(b) {}
int x, y;
};
struct B {
B(int a, int b, int c) : x(a), y(b), z(c) {}
int x, y, z;
};
template<typename T, typename... TArgs>
T* createElement(TArgs&&... MArgs) {
T* element = new T(std::forward<TArgs>(MArgs)...);
return element;
}
int main() {
int Aargs[] = { 1, 2 };
int Bargs[] = { 1, 2, 3 };
A* a = createElement<A>(Aargs); //ERROR
B* b = createElement<B>(Bargs); //ERROR
std::cout << "a.x: " << a->x << "\na.y: " << a->y << "\n" << std::endl;
std::cout << "b.x: " << b->x << "\nb.y: " << b->y << "\nb.z: " << b->z << "\n" << std::endl;
delete a;
delete b;
}
Is there any way to expand the arrays so that each of their values is like an argument being passed to the function (similar to parameter pack expansion)?
Or, if not, is there any other way to make this work?

You can expand the array using a std::index_sequence
#include <iostream>
#include <utility>
struct A {
A(int a, int b) : x(a), y(b) {}
int x, y;
};
struct B {
B(int a, int b, int c) : x(a), y(b), z(c) {}
int x, y, z;
};
template<typename T, typename... TArgs>
T* createElement(TArgs&&... MArgs) {
T* element = new T(std::forward<TArgs>(MArgs)...);
return element;
}
template<typename T, typename U, size_t... I>
T* createElementFromArrayHelper(std::index_sequence<I...>, U* a){
return createElement<T>(a[I]...);
}
template<typename T, typename U, size_t N>
T* createElementFromArray(U (&a)[N]){
return createElementFromArrayHelper<T>(std::make_index_sequence<N>{}, a);
}
int main() {
int Aargs[] = { 1, 2 };
int Bargs[] = { 1, 2, 3 };
A* a = createElementFromArray<A>(Aargs);
B* b = createElementFromArray<B>(Bargs);
std::cout << "a.x: " << a->x << "\na.y: " << a->y << "\n" << std::endl;
std::cout << "b.x: " << b->x << "\nb.y: " << b->y << "\nb.z: " << b->z << "\n" << std::endl;
delete a;
delete b;
}

Related

Find Dimension of Array

I am trying to count the # of dimension:
template <class T>
struct dimension {
static constexpr auto n = 0;
void print() {
std::cout << "T is not an array: " << __PRETTY_FUNCTION__ << std::endl;
}
};
template <class T, size_t N>
struct dimension<T(&)[N]> {
static constexpr auto n = 1 + dimension<T>::n;
void print() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
dimension<T> d;
d.print();
}
};
int main() {
int x[6][3];
dimension<decltype((x))> d;
d.print();
}
And the output:
void dimension<T (&)[N]>::print() [with T = int [3]; long unsigned int N = 6]
T is not an array: void dimension<T>::print() [with T = int [3]]
However, for some reason, when dimension<T>::n in the partial specialized template, it actually instantiate dimension<int[3]> instead of dimension<int, 3>. What did I do wrong?
Thanks!

use enum type to manage storage order

I'm trying to use enum types to indexig some array but I want to allow different ordering of the vector depending on some option. In the class I also want functions that take the enum variable as input and use it as it should.
The solution I found is the following
#include<iostream>
#include<array>
#include<vector>
struct A{
struct XYZ{
enum coord{X=0,Y,Z};
};
struct YZX{
enum coord{Y=0,Z,X};
};
struct ZXY{
enum coord{Z=0,X,Y};
};
std::array<std::vector<float>,3> val;
void resize(int opt, size_t dim){
val[opt].resize(dim);
return;
}
void printsize(){
for(auto & i : val){
std::cout << i.size() << " ";
}
std::cout << std::endl;
return;
}
};
int main(){
A foo1;
A foo2;
A foo3;
foo1.resize(XYZ::X,10);
foo2.resize(YZX::X,10);
foo3.resize(ZXY::X,10);
std::cout << "Size foo1\n";
foo1.printsize();
std::cout << "Size foo2\n";
foo2.printsize();
std::cout << "Size foo3\n";
foo3.printsize();
return 0;
}
What I don't like in this solution is that my function resize takes an integer type as input and there's no type control of the enum.
Is there any other smarter solution? Am I doing something considered as anti-pattern?
Thank you
I suggest you to modify the member function resize (three parameters instead of two) and exploit the type safety of the enum classes:
#include <stdio.h>
#include<iostream>
#include<array>
#include<vector>
struct A{
enum class Coordinate
{
X = 0,
Y = 1,
Z = 2
};
enum class Permutation
{
XYZ = 0,
ZXY = 1,
YZX = 2
};
std::array<std::vector<float>,3> val;
/* resize takes three parameters now */
void resize(Permutation p, Coordinate c, size_t dim)
{
int index = ( static_cast<int>(p) + static_cast<int>(c) ) % 3 ;
val[index].resize(dim);
return;
}
void printsize(){
for(auto & i : val){
std::cout << i.size() << " ";
}
std::cout << std::endl;
return;
}
};
int main()
{
A foo1;
A foo2;
A foo3;
foo1.resize(A::Permutation::XYZ, A::Coordinate::X,10);
foo2.resize(A::Permutation::YZX, A::Coordinate::X,10);
foo3.resize(A::Permutation::ZXY, A::Coordinate::X,10);
std::cout << "Size foo1\n";
foo1.printsize();
std::cout << "Size foo2\n";
foo2.printsize();
std::cout << "Size foo3\n";
foo3.printsize();
return 0;
}
How about an Index class, constructible from several enum classes?
struct A
{
enum class XYZ {X,Y,Z};
enum class YZX {Y,Z,X};
enum class ZXY {Z,X,Y};
struct Index
{
int value;
operator int() const {return value;}
Index(XYZ value) : value(int(value)) {}
Index(YZX value) : value(int(value)) {}
Index(ZXY value) : value(int(value)) {}
};
std::array<std::vector<float>, 3> val;
void resize(Index opt, size_t dim)
{
val[opt].resize(dim);
}
void printsize() const
{
for (const auto &i : val)
std::cout << i.size() << ' ';
std::cout << '\n';
}
};

Can I give different behaviours to boost::proto::tag types?

I am trying to use boost proto to lazily evaluate expressions, what I want to do is be able to give different behaviours to tags like +, -, function etc.
function(
terminal(8functionILi2EE)
, plus(
multiplies(
terminal(6tensorILi0EE)
, terminal(6tensorILi1EE)
)
, multiplies(
terminal(6tensorILi2EE)
, terminal(6tensorILi3EE)
)
)
)
For a tree like above, I want to be able to specify how each of the tree nodes should behave.
For eg.
struct context : proto::callable_context< context const >
{
// Values to replace the tensors
std::vector<double> args;
// Define the result type of the zero.
// (This makes the zero_context "callable".)
typedef double result_type;
// Handle the tensors:
template<int I>
double operator()(proto::tag::terminal, tensor<I>) const
{
std::cout << this->args[I] << std::endl;
return this->args[I];
}
template<int I>
void operator()(proto::tag::plus) const
{
std::cout << " + " << std::endl;
}
};
When I do
double result = (_tensorA + _tensorB)(10, 20);
I expect my output to be
10
+
20
But it's just
10
20
Any help would be deeply appreciated! :)
template<int I>
void operator()(proto::tag::plus) const
{
std::cout << " + " << std::endl;
}
The template argument I is non-deducible, so the overload will never be applicable. Drop the template argument:
void operator()(proto::tag::plus) const
{
std::cout << " + " << std::endl;
}
HOWEVER What you really want is intercept the binary operator. Well. Note it's binary. So it has two args:
template<size_t I, size_t J>
void operator()(proto::tag::plus, proto::literal<tensor<I>>&, proto::literal<tensor<J>>&) const {
std::cout << " + " << std::endl;
}
Live On Coliru
However, this blocks further evaluation of the expression tree. Not what you wanted, right. So, let's do a simplisitic re-implementation:
template<size_t I, size_t J>
double operator()(proto::tag::plus, proto::literal<tensor<I>>& a, proto::literal<tensor<J>>& b) const {
auto va = (*this)(proto::tag::terminal{}, a.get());
std::cout << " + " << std::endl;
auto vb = (*this)(proto::tag::terminal{}, b.get());
return va + vb;
}
Live On Coliru
Generic, please
However, something tells me you wanted generic expressions. So t1 + (t2 + t3) should also work, but (t2 + t3) is no literal...
Let's simplify by delegating:
template<typename A, typename B>
double operator()(proto::tag::plus, A& a, A& b) const {
auto va = proto::eval(a, *this);
std::cout << " + " << std::endl;
auto vb = proto::eval(b, *this);
return va + vb;
}
Full Sample
Live On Coliru
#include <boost/proto/proto.hpp>
#include <vector>
namespace proto = boost::proto;
template <size_t N> struct tensor { };
template <size_t N, size_t M> tensor<N+M> operator+(tensor<N>, tensor<M>) { return {}; }
struct context : proto::callable_context< context const >
{
using base_type = proto::callable_context<context const>;
// Values to replace the tensors
std::vector<double> args { 0, 111, 222, 333 };
// Define the result type of the zero.
// (This makes the zero_context "callable".)
typedef double result_type;
// Handle the tensors:
template<size_t I>
double operator()(proto::tag::terminal, tensor<I>) const
{
std::cout << this->args[I] << std::endl;
return this->args[I];
}
template<typename A, typename B>
double operator()(proto::tag::plus, A& a, B& b) const {
auto va = proto::eval(a, *this);
std::cout << " + " << std::endl;
auto vb = proto::eval(b, *this);
return va + vb;
}
};
int main() {
proto::literal<tensor<1> > t1;
proto::literal<tensor<2> > t2;
proto::literal<tensor<3> > t3;
auto r = proto::eval(t1 + (t2 + t3), context());
std::cout << "eval(t1 + (t2 + t3)) = " << r << "\n";
}
Prints
111
+
222
+
333
eval(t1 + (t2 + t3)) = 666

C++ std::function variable with varying arguments

In my callback system I want to store std::function (or something else) with varying arguments.
Example:
I want to call void()
I want to call void(int, int)
I want 1) and 2) to be stored in the same variable and choose what to call in actuall call
FunctionPointer f0;
FunctionPointer f2;
f0();
f2(4, 5);
Is it possible to do something like this? Or I have to create several "FuntionPointer" templates based on input arguments count.
EDIT
Is it possible to utilize std::bind somehow for this task? With std::bind I can have std::function<void()> f = std::bind(test, 2, 5);
EDIT 2
Practical use case: I have a trigger system and I want to assign funtion pointers to actions, so when action happen, function is called.
Pseudo-code sample:
structure Trigger
{
Function f;
}
Init:
Trigger0.f = pointer to some function ()
Trigger1.f = pointer to some function (a, b)
Input:
Find Trigger by input
if (in == A) Trigger.f();
else Trigger.f(10, 20)
or if possible
Input:
Find Trigger by input
if (in == A) f = bind(Trigger.f);
else f = bind(Trigger.f, 10, 20);
f()
std::function<void()> and std::function<void(int, int)> are two absolutely distinct types. You need some sort of union functionality (or polymorphism) to store an object of an unknown type.
If you can use Boost, you could easily do this with boost::variant:
// Declaration:
boost::variant<std::function<void()>, std::function<void(int, int)> > f;
// Calling, explicit:
if (fContainsNullary()) {
boost::get<std::function<void()>>(f)();
} else {
boost::get<std::function<void(int, int)>>(f)(4, 5);
}
It is up to you to provide the logic of fContainsNullary(). Alternatively, you can use the variant's own stored knowledge of value type by using a visitor:
struct MyVisitor : boost::static_visitor<void>
{
result_type operator() (const std::function<void()> &a) {
a();
}
result_type operator() (const std::function<void(int, int)> &a) {
a(4, 5);
}
};
// Calling, via visitor:
boost::apply_visitor(MyVisitor(), f);
If Boost is not an option, you can hand-craft a suitable union for much the same purpose.
The following solution might work for you (I'm not sure that the code is absolutely correct here):
Create a wrapper for std::function with virtual destructor to enable using dynamic cast
class function_wrapper_base
{
virtual ~function_wrapper_base();
}
template <class... Args>
class function_wrapper
: public function_wrapper_base
{
public:
std::function<void, Args...> f;
...
};
Then create a class variant_function_holder
class variant_function_holder
{
std::unique_ptr<function_wrapper_base> f;
...
template <class... Args>
void operator()(Args&&... args)
{
function_wrapper<std::decay<Args>::type...> * g = dynamic_cast<function_wrapper<std::decay<Args>::type...>>(f.get());
if (g == nullptr)
{
// ToDo
}
g->f(std::forward<Args>(args)...);
}
};
Well, if you can use RTTI, you can define a MultiFuncObject like this, and you can easily bind other functions. Also, you can easily call them. But unfortunately, this approach only works for a limited number of arguments. But actually boost::bind also supports limited number of arguments (by default 9). So you can extend this class to satisfy your needs.
Before giving you the source of MultiFuncObject, I want to show you how you can use it. It takes an template argument to be used as return type. You can bind new functions with += operator. With some template magic, the class distinguishes differences between bound functions with same count of arguments with at least one different argument type.
You need C++11, because MultiFuncObject uses std::unordered_map and std::type_index.
Here is usage:
#include <iostream>
using namespace std;
void _1() {
cout << "_1" << endl;
}
void _2(char x) {
cout << "_2" << " " << x << endl;
}
void _3(int x) {
cout << "_3" << " " << x << endl;
}
void _4(double x) {
cout << "_4" << " " << x << endl;
}
void _5(int a, int b) {
cout << "_5" << " " << a << " " << b << endl;
}
void _6(char a, int b) {
cout << "_6" << " " << a << " " << b << endl;
}
void _7(int a, int b, int c) {
cout << "_7" << " " << a << " " << b << " " << c << endl;
}
int main() {
MultiFuncObject<void> funcs;
funcs += &_1;
funcs += &_2;
funcs += &_3;
funcs += &_4;
funcs += &_5;
funcs += &_6;
funcs += &_7;
funcs();
funcs('a');
funcs(56);
funcs(5.5);
funcs(2, 5);
funcs('q', 6);
funcs(1, 2, 3);
return 0;
}
I hope this is close to what you want. Here is the source of MultiFuncObject:
#include <typeinfo>
#include <typeindex>
#include <unordered_map>
using namespace std;
template <typename R>
class MultiFuncObject {
unordered_map<type_index, void (*)()> m_funcs;
public:
MultiFuncObject<R> operator +=( R (* f)() ) {
m_funcs[typeid( R() )] = (void (*)()) f;
return *this;
}
template <typename A1>
MultiFuncObject<R> operator +=( R (* f)(A1) ) {
m_funcs[typeid( R(A1) )] = (void (*)()) f;
return *this;
}
template <typename A1, typename A2>
MultiFuncObject<R> operator +=( R (* f)(A1, A2) ) {
m_funcs[typeid( R(A1, A2) )] = (void (*)()) f;
return *this;
}
template <typename A1, typename A2, typename A3>
MultiFuncObject<R> operator +=( R (* f)(A1, A2, A3) ) {
m_funcs[typeid( R(A1, A2, A3) )] = (void (*)()) f;
return *this;
}
R operator()() const
{
unordered_map<type_index, void (*)()>::const_iterator it = m_funcs.find(typeid( R() ));
if (it != m_funcs.end()) {
R (*f)() = ( R (*)() )(it->second);
(*f)();
}
}
template <typename A1>
R operator()(A1 a1) const
{
unordered_map<type_index, void (*)()>::const_iterator it = m_funcs.find(typeid( R(A1) ));
if (it != m_funcs.end()) {
R (*f)(A1) = ( R (*)(A1) )(it->second);
(*f)(a1);
}
}
template <typename A1, typename A2>
R operator()(A1 a1, A2 a2) const
{
unordered_map<type_index, void (*)()>::const_iterator it = m_funcs.find(typeid( R(A1, A2) ));
if (it != m_funcs.end()) {
R (*f)(A1, A2) = ( R (*)(A1, A2) )(it->second);
(*f)(a1, a2);
}
}
template <typename A1, typename A2, typename A3>
R operator()(A1 a1, A2 a2, A3 a3) const
{
unordered_map<type_index, void (*)()>::const_iterator it = m_funcs.find(typeid( R(A1, A2, A3) ));
if (it != m_funcs.end()) {
R (*f)(A1, A2, A3) = ( R (*)(A1, A2, A3) )(it->second);
(*f)(a1, a2, a3);
}
}
};
It stores different function prototypes using std::unordered_map with keys of std::type_index and values of void (*)(). When needed, the correct function is retrieved using that map.
Here is the working example
C++11 to the rescue!
If you can generalize your function to a functor object taking no arguments, then you can call it with any lambda.
#include <iostream>
using namespace std;
template <class F>
void call_it(F&& f)
{
f();
}
int main()
{
int x = 50, y = 75;
call_it([] () { cout << "Hello!\n"; });
call_it([x,y] () { cout << x << " + " << y << " = " << x + y << '\n';});
return 0;
}
If std::function is not necessary for you, you can create a proxy class.
class fn_t {
public:
typedef void (*fn_1_t)();
typedef void (*fn_2_t)(int, int);
fn_1_t fn_1;
fn_2_t fn_2;
fn_t operator=(fn_1_t func_1) { fn_1 = func_1; return *this; }
fn_t operator=(fn_2_t func_2) { fn_2 = func_2; return *this; }
void operator()() { (*fn_1)(); }
void operator()(int a, int b) { (*fn_2)(a, b); }
};
#include <iostream>
using namespace std;
void first() {
cout << "first" << endl;
}
void second(int a, int b) {
cout << "second " << a << " : " << b << endl;
}
int main() {
fn_t f;
f = &first;
f = &second;
f();
f(5, 4);
return 0;
}
Class fn_t automatically works with two prototypes you want, assigns automatically needed one, and it can call functions with both prototypes by overlading () operator with appropriate parameters.
You may want to check for validity of function pointers fn_1 and fn_2 but I didn't include this checking for minimality.
The advantage of this is that you only need C++ and not even STL and Boost.
The other answers are fine but I want to show my solution as well.
It's a small header with which you can "elongate" function signatures.
This allows you to do this (extract from the github example):
int foo_1p(int a);
int foo_2p(int a, int b);
int foo_3p(int a, int b, int c);
int foo_4p(int a, int b, int c, int d);
int foo_5p(int a, int b, int c, int d, int e);
int foo_6p(int a, int b, int c, int d, int e, int f);
int foo_7p(int a, int b, int c, int d, int e, int f, std::string g);
...
int main()
{
std::unordered_map<std::string, std::function<int(int, int, int, int, int, int, std::string)>> map;
map["foo_1p"] = ex::bind(foo_1p, ph, ph, ph, ph, ph, ph);
map["foo_2p"] = ex::bind(foo_2p, ph, ph, ph, ph, ph);
map["foo_3p"] = ex::bind(foo_3p, ph, ph, ph, ph);
map["foo_4p"] = ex::bind(foo_4p, ph, ph, ph);
map["foo_5p"] = ex::bind(foo_5p, ph, ph);
map["foo_6p"] = ex::bind(foo_6p, ph);
map["foo_7p"] = foo_7p;
for (const auto& f : map)
{
std::cout << f.first << " = " << f.second(1, 1, 1, 1, 1, 1, "101") << std::endl;
}
}

Lambda functions as class members

Is it possible to accept two different types of lambda function as class members without knowing their template arguments ahead of time?
struct two_functors {
std::function<???> a;
std::function<???> b;
...
};
Such that something like this would be possible:
void main(){
vector<two_functors> many_functors;
int a = 2;
int b = 3;
double c = 4.7;
double d = 8.4;
two_functors add_and_subtract;
add_and_subtract.a = [a, b](int x, int y){cout << x + y << endl;};
add_and_subtract.b = [c, d](double x, double y){cout << x - y << endl;};
two_functors multiply_and_divide;
multiply_and_divide.a = [c, d](double x, double y){cout << x * y << endl;};
multiply_and_divide.b = [a, b](int x, int y){cout << x / y << endl;};
many_functors.push_back(add_and_subtract);
many_functors.push_back(multiply_and_divide);
for (auto functors : many_functors){
functors.a();
functors.b();
}
}
If you just want to construct two_functors at various times, but execute them later in sequence all at once, you could just use the captured data.
struct two_functors
{
function<void ()> a;
function<void ()> b;
};
int main()
{
vector<two_functors> many_functors;
int a = 2;
int b = 3;
double c = 4.7;
double d = 8.4;
two_functors add_and_subtract {
[a, b](){cout << a + b << endl;},
[c, d](){cout << c - d << endl;}
};
two_functors multiply_and_divide {
[c, d](){cout << c * d << endl;},
[a, b](){cout << a / b << endl;}
};
many_functors.push_back(add_and_subtract);
many_functors.push_back(multiply_and_divide);
for (auto functors : many_functors){
functors.a();
functors.b();
}
}
That's essentially a tuple. You can see how the interface is implemented for that.
template< class F0, class F1 >
struct two_functors {
F0 func0;
F1 func1;
};
template< class F0, class F1 >
two_functors<F0, F1> make_two_functor( F0&& f0, F1&& f1 )
{
// Added [std::forward][2]
return two_functors<F0,F1>( std::forward<F0>(f0), std::forward<F1>(f1) );
}
Not an attempt to answer (I just need the formatting feat), just a variation of Steven's proposal
template<typename A, typename B>
two_functors<A,B> make_two_functors(A&& a, B&& b) {
return two_functors<A,B> {a, b};
}
Does that have any downside compared to using std::forward<T>?
Btw - I somehow wish the need for such "makers" would have vanished with C++11.
An alternative to Steven's answer would be to use an intermediate "umbrella" class.
EDIT: Just compiled an example on g++ (GCC) 4.5.3
#include <functional>
#include <iostream>
using namespace std;
class myfunction
{
};
template <typename T>
class specificFunction : public myfunction
{
public:
function<T> f;
specificFunction(function<T> pf)
{
f = pf;
}
};
struct two_functors {
myfunction* a;
myfunction* b;
};
int main()
{
myfunction* f = new specificFunction<void(int,int)> ([](int a, int b) { cout << a << " - " << b << endl; });
myfunction* f2 = new specificFunction<void(double,int)> ([](double a, int b) { cout << a << " - " << b << endl; });
two_functors tf;
tf.a = f;
tf.b = f2;
((specificFunction<void(int,int)>*)(tf.a))->f(4,5);
((specificFunction<void(double,int)>*)(tf.b))->f(4.02,5);
}