C++11 passing variadic number of objects by reference to function - c++

I'm trying to pass a variable number of objects by reference in C++11.
The C-style of variadic argumnets did not seem very elegant, so I tried using the std::initialiszer_list.
But all the examples i found used pass by copy, I wrote a simple example of what I want to achieve:
//Example class for illustration purposes
class MyClass
{
public:
MyClass()
: m_id(0), m_idChecks(0)
{}
~MyClass(){}
int getId()
{
m_idChecks++;
return m_id;
}
int getIdChecks() const
{
return m_idChecks;
}
private:
int m_id;
int m_idChecks;
};
// I want to do something like this (pass the objects by reference):
// void test_initializerList(std::initializer_list<MyClass&> listClasses)
// But only pass by copy works:
void test_initializerList(std::initializer_list<MyClass> listClasses)
{
// Doing operations on copies of the object:
int sum = 0;
for(auto c : listClasses)
{
sum += c.getId();
}
std::cout << "\n id: " << sum;
}
void test()
{
MyClass c1;
MyClass c2;
MyClass c3;
test_initializerList({c1,c2,c3});
std::cout << "\n Wanted: " << 1 << " id checks, got: " << c1.getIdChecks() << "\n";
}
So how do you pass a variable number of arguments in modern C++? Examples are appreciated!

Unfortunately, initializer_list can only copy it's arguments, and can't hold a reference to it (directly at least). However, there is way around it (example trimmed):
#include <initializer_list>
#include <iostream>
#include <functional>
//Example class for illustration purposes
class MyClass
{
public:
MyClass() : m_idChecks(0) {}
~MyClass(){}
int getId() const
{
return m_idChecks++;
}
int getIdChecks() const
{
return m_idChecks;
}
private:
mutable int m_idChecks;
};
using r = std::reference_wrapper<MyClass>;
void test_initializerList(std::initializer_list<r> listClasses)
{
// Doing operations on copies of the object:
int sum = 0;
for(const auto& c : listClasses)
{
sum += c.get().getId();
}
}
int main()
{
MyClass c1;
MyClass c2;
MyClass c3;
test_initializerList({c1,c2,c3});
std::cout << "\n Wanted: " << 1 << " id checks, got: " << c1.getIdChecks() << "\n";
}

Related

Can i use C++ function pointers like a C#'s Action?

In C ++, I first encountered function pointers.
I tried to use this to make it similar to Action and Delegate in C #.
However, when declaring a function pointer, it is necessary to specify the type of the class in which the function exists.
ex) void (A :: * F) ();
Can I use a function pointer that can store a member function of any class?
In general, function pointers are used as shown in the code below.
class A {
public:
void AF() { cout << "A::F" << endl; }
};
class B {
public:
void(A::*BF)();
};
int main()
{
A a;
B b;
b.BF = &A::AF;
(a.*b.BF)();
return 0;
}
I want to use it like the code below.
is this possible?
Or is there something else to replace the function pointer?
class A {
public:
void AF() { cout << "A::F" << endl; }
};
class B {
public:
void(* BF)();
};
int main()
{
A a;
B b;
b.BF = a.AF;
return 0;
}
I solved the question through the answer.
Thanks!
#include <functional>
#include <iostream>
class A {
public:
void AF() { std::cout << "A::F" << std::endl; }
};
class C {
public:
void CF() { std::cout << "C::F" << std::endl; }
};
class B {
public:
B(){}
std::function<void()> BF;
};
int main() {
A a;
C c;
B b;
b.BF = std::bind(&A::AF, &a);
b.BF();
b.BF = std::bind(&C::CF, &c);
b.BF();
int i;
std::cin >> i;
return 0;
}
What you want to do is probably something like this. You can use std::function to hold a pointer to a member function bound to a specific instance.
#include <functional>
#include <iostream>
class A {
public:
void AF() { std::cout << "A::F" << std::endl; }
};
class B {
public:
B(const std::function<void()>& bf) : BF(bf) {}
std::function<void()> BF;
};
int main() {
A a;
B b1(std::bind(&A::AF, &a)); // using std::bind
B b2([&a] { a.AF(); }); // using a lambda
b1.BF();
b2.BF();
return 0;
}
Here's a C# style implementation of the accepted answer, It is memory efficient and flexible as you can construct and delegate at different points of execution which a C# developer might expect to do:
#include <iostream>
#include <functional>
using namespace std;
class A {
public:
void AF() { cout << "A::F" << endl; }
void BF() { cout << "B::F" << endl; }
};
class B {
public:
std::function<void()> Delegate;
};
int main() {
A a;
B b;
b.Delegate = std::bind(&A::AF, &a);
b.Delegate();
b.Delegate = [&a] { a.BF(); };
b.Delegate();
return 0;
}

C++ Avoiding using copy constructor which is called by priorityqueue

I have this current setup:
#include <iostream>
#include <queue>
#include <vector>
class A
{
int val;
public:
A()
{
std::cout << "Inside A. Constructor with val =" << val << ".\n";
}
A(const A& msg)
{
std::cout << "Inside const A. Never want to come here. val =" << msg.val << ".\n";
}
bool operator()(const A* m1, const A* m2)
{
std::cout << "Inside () function.\n";
std::cout << "m1: " << m1->GetVal() << " m2: " << m2->GetVal()<<"\n";
return (m1->GetVal() < m2->GetVal());
}
void setVal(int input) { std::cout << "inside setVal.\n"; val = input; }
int GetVal()const { return val; }
};
void specialPriorityQueue()
{
//init
A* val = new A();
val->setVal(5);
std::priority_queue<A*, std::vector<A*>, A> pq;
pq.push(val);
A* val2 = new A();
val2->setVal(3);
pq.push(val2);
delete val;
delete val2;
}
int main()
{
specialPriorityQueue();
return 0;
}
outputs:
Inside A. Constructor with val =-85000000...
inside setVal.
Inside A. Constructor with val =-85000000...
Inside const A. Never want to come here. val =-85000000....
Inside A. Constructor with val =-85000000...
inside setVal.
Inside const A. Never want to come here. val =-85000000....
Inside () function.
m1: 5 m2: 3
My question is: Is there any way to avoid using the copy constructor by the priority queue. This causes undefined behaviour. I can't remove the function either as it has too much dependencies elsewhere.
That copy constructor is called when it creates the comparator object, which is also your element type, A.
Use another type for comparator, e.g.:
struct Compare
{
bool operator()(const A* m1, const A* m2) const {
return m1->GetVal() < m2->GetVal();
}
};
And then:
std::priority_queue<A*, std::vector<A*>, Compare> pq;
And, even better, use smart pointers to avoid memory leaks:
struct Compare
{
bool operator()(std::unique_ptr<A> const& m1, std::unique_ptr<A> const& m2) const {
return m1->GetVal() < m2->GetVal();
}
};
void specialPriorityQueue() {
std::unique_ptr<A> val(new A());
val->setVal(5);
std::priority_queue<std::unique_ptr<A>, std::vector<std::unique_ptr<A>>, Compare> pq;
pq.push(move(val));
std::unique_ptr<A> val2(new A());
val2->setVal(3);
pq.push(move(val2));
}

out parameters in c++ pass by reference

I want to achieve something similar in c++. This here is a c# code. I want to avoid raw pointers as much as possible.
class Program
{
public class Foo
{
public int v1;
public int v2;
public Foo(int a, int b)
{
v1 =a; v2 =b;
}
};
public class Bar
{
public static void getFoo(out Foo fooObj)
{
fooObj = new Foo(1,2);
}
};
static void Main()
{
Foo fooObj = null;
Bar.getFoo(out fooObj);
Console.WriteLine("Foo.v1="+fooObj.v1);
Console.WriteLine("Foo.v2="+fooObj.v2);
}
}
Here goes my attempt to convert your C# code into C++. However, once you run it you need to do proper research on how to use use all the features I've used here. unique_ptr will basically manage the "raw" pointer for you (which is what you want, and it will free it once it goes out of scope). I've added an improved version using variadic templates so you can pass any number of arguments of any type to dynamically create your Foo class.
#include <memory>
#include <iostream>
class Foo
{
public:
int v1;
int v2;
Foo(int a, int b)
{
v1 =a; v2 =b;
}
};
class Bar
{
public:
// This is what your function looks like in C++
static void getFoo(std::unique_ptr<Foo>& fooObj)
{
fooObj = std::make_unique<Foo>(1, 2);
}
// This is a better implementation.
template<typename ...Args>
static void getFoo_improved(std::unique_ptr<Foo>& fooObj, Args&&... args)
{
fooObj = std::make_unique<Foo>(std::forward<Args>(args)...);
}
// This is the one used more often in C++ tho.
template<typename ...Args>
static std::unique_ptr<Foo> getFoo_improved_x2(Args&&... args)
{
return std::make_unique<Foo>(std::forward<Args>(args)...);
}
};
int main()
{
std::unique_ptr<Foo> fooObj = nullptr; //nullptr is not needed tho
Bar::getFoo(fooObj);
std::unique_ptr<Foo> fooObj_alt = nullptr; //nullptr is not needed tho
Bar::getFoo_improved(fooObj_alt, 9, 10);
//This is as fast as the other two
auto fooObj_alt_x2 = Bar::getFoo_improved_x2(50, 60);
std::cout << "Foo.v1=" << fooObj->v1 << std::endl;
std::cout << "Foo.v2=" << fooObj->v2 << std::endl;
std::cout << "Foo_alt.v1=" << fooObj_alt->v1 << std::endl;
std::cout << "Foo_alt.v2=" << fooObj_alt->v2 << std::endl;
std::cout << "Foo_alt_x2.v1=" << fooObj_alt_x2->v1 << std::endl;
std::cout << "Foo_alt_x2.v2=" << fooObj_alt_x2->v2 << std::endl;
return 0;
}

OOP: Passing primitive types to function that expects objects

Is it possible to pass constructor arguments to a function instead of the class object itself ?
According to the following code
#include <iostream>
#include <string>
class CL{
public:
int id;
CL(){
std::cout << "CL () Constructor " << std::endl;
}
CL(const char * name){
std::cout << " CL(const char * name) Constructor Called " << std::endl;
}
CL(int i){
id = i;
std::cout << "CL(int i) Constructor Called " << id << std::endl;
}
void print(){
std::cout << "print method Called " << id << std::endl;
}
};
void myfunc(CL pp){
pp.print();
}
int main(int argc,char **argv){
myfunc(10);
}
I passed integer to the function "myfunc" instead of class instance and it worked. I think it instantiated object on the fly.
the output is
CL(int i) Constructor Called 10
print method Called 10
is it such an ambiguity ? as for the same code if I overloaded the function
"myfunc" as
myfunc(int i) {
std::cout << i << std::endl;
}
it will output
10
and ignore the function prototype that takes the class object
This is called implicit conversion and works for all constructors, that take a single parameter. In cases, where you don't want that, declare the constructor explicit:
class CL {
public:
int id;
CL(): id{0} {}
explicit CL(int i): id{i} {}
};
void myfunc(CL pp) {
// ...
}
int main(int, char) {
myfunc(10); // <- will fail to compile
}

Calling std::function object pointing to the method of deallocated object

Consider this code:
#include <iostream>
#include <functional>
using namespace std;
using namespace std::placeholders;
typedef function<void(const int&)> SomeFunc;
class X {
public:
X(string name):name_(name)
{ cout << "ctor " << name_ << endl; }
~X()
{
cout << "dtor " << name_ << endl;
name_ = "empty";
}
SomeFunc
getSomeFunc()
{ return bind(&X::someMethod, this, _1); }
private:
string name_;
void
someMethod(const int& a)
{
cout << name_ << " some method with " << a << endl;
}
};
int main()
{
SomeFunc f;
{
shared_ptr<X> x(new X("Object"));
f = x->getSomeFunc();
f(1);
}
f(2);
return 0;
}
Sometimes, output gives me this:
ctor Object
Object some method with 1
dtor Object
empty some method with 2
other times this:
ctor Object
Object some method with 1
dtor Object
some method with 2
In real world, it would most probably give me crashes once deallocated object tries to access it's attributes.
So here is a question - as function does not guarantee holding a reference to the object which method it's pointing to, what is the best practice to avoid crashes when function is called after referenced object was already deallocated?
One of the solutions I might think of - maintain a special flag bool deallocated_ inside object and check it inside the method which might be called after deallocation. However, I suspect, it's not reliable either.
UPDATE (from comments):
The real reason I need this workaround is the library that takes function as a parameter. This library operates asynchronously and I have no control over function objects passed into it. That's why when my object is deallocated, library still can invoke callbacks using originally passed function which leads to a crash.
Your object is being held by a shared_ptr, so you can use a lambda to close over the shared_ptr:
auto func = [ptr](const int &p){ ptr->someMethod(p); };
You'll need to use shared_from_this to get ptr within the class.
Here's a full example that works:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
using namespace std::placeholders;
typedef function<void(const int&)> SomeFunc;
class X : public enable_shared_from_this<X> {
public:
X(string name) : name_(name) {
cout << "ctor " << name_ << endl;
}
~X() {
cout << "dtor " << name_ << endl;
name_ = "empty";
}
SomeFunc getSomeFunc() {
auto ptr = shared_from_this();
return [ptr](const int &a){ ptr->someMethod(a); };
}
private:
string name_;
void someMethod(const int& a) {
cout << name_ << " some method with " << a << endl;
}
};
int main()
{
SomeFunc f;
{
shared_ptr<X> x(new X("Object"));
f = x->getSomeFunc();
f(1);
}
f(2);
return 0;
}
The output looks like this:
ctor Object
Object some method with 1
Object some method with 2
dtor Object
Sulution 1) Using weak_ptr + lambda (almost the same as from b4hand, but it won't force your class beeing alive)
Inherit your class from std::enable_shared_from_this
class X : public enable_shared_from_this<X>
and change getSomeFunc to something like this:
SomeFunc getSomeFunc()
{
weak_ptr<X> weak = shared_from_this();
return [weak, this](const int& a){
shared_ptr<X> shared = weak.lock();
if (shared)
{
this->someMethod(a);
}
};
}
output:
ctor Object
Object some method with 1
dtor Object
more details here and here.
Solution 2) A bit of crazy code + lambda
If you can't or don't want to use shared/weak ptrs, you can do it this way:
#include <memory>
#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include <set>
using namespace std;
typedef function<void(const int&)> SomeFunc;
class X {
private:
static set<X*> _aliveInstanties;
public:
X(string name) :name_(name)
{
_aliveInstanties.insert(this);
cout << "ctor " << name_ << endl;
}
~X()
{
_aliveInstanties.erase(_aliveInstanties.find(this));
cout << "dtor " << name_ << endl;
name_ = "empty";
}
SomeFunc getSomeFunc()
{
return [this](const int& a)
{
if (_aliveInstanties.find(this) != _aliveInstanties.end())
{
this->someMethod(a);
}
};
}
private:
string name_;
void someMethod(const int& a)
{
cout << name_ << " some method with " << a << endl;
}
};
You can create a class that holds a function pointer and a shared_ptr to the object. The shared_ptr to the object guarantees the object won't be destroyed until your function class is destroyed.
Another solution without using lambda is to derive from enable_shared_from_this and pass shared_from_this in getSomeFunc method:
class X : public enable_shared_from_this<X> {
public:
X(string name):name_(name)
{ cout << "ctor " << name_ << endl; }
~X()
{
cout << "dtor " << name_ << endl;
name_ = "empty";
}
SomeFunc
getSomeFunc()
{
return bind(&X::someMethod, shared_from_this(), _1);
}
private:
string name_;
void
someMethod(const int& a)
{
cout << name_ << " some method with " << a << endl;
}
};
This, however, will hold object until all callbacks are released.