class foo {
foo();
unique_ptr<T, (void *)(T*)> ptr;
};
foo::foo() {
bool x = some operation;
if (!x) throw;
ptr = unique_ptr<T, (void *)(T*)>(new T(x), deleter);
}
This code does not compile because the unique pointer and its deleter get initialized with null (as I don't initialize it in the initializer list). I can't initialize it in the list because it's dependent on the variable x as shown above. How can I solve this deadlock?
Try this:
foo()
: ptr(nullptr, deleter)
{
if (!some operation) { throw AppropriateException(); }
ptr.reset(new T(true));
}
One solution would be to add a static function that determines what x should be and then return it to the constructor of the unique_ptr in the member initialization list
foo() : ptr(construct_t(), deleter) {}
static T* construct_t()
{
bool x = some operation;
if(!x) throw;
return new T(x);
}
working example of using a generator and custom deleter:
#include <iostream>
#include <memory>
#include <vector>
struct bar {};
struct bar_deleter {
void operator()(bar* p) const noexcept {
try {
if (p) {
std::cout << "deleting p" << std::endl;
}
else {
std::cout << "not deleting p" << std::endl;
}
}
catch(...) {
}
}
};
bool some_condition()
{
static int counter = 0;
return (counter++ % 2) == 0;
}
struct foo {
using ptr_type = std::unique_ptr<bar, bar_deleter>;
foo()
: ptr(bar_generator())
{}
static ptr_type bar_generator() {
if (some_condition()) {
std::cout << "creating bar" << std::endl;
return { new bar, bar_deleter{} };
}
else {
std::cout << "not creating bar" << std::endl;
return { nullptr, bar_deleter{} };
}
}
ptr_type ptr;
};
int main()
{
using namespace std;
auto v = std::vector<foo>(10);
return 0;
}
expected results:
creating bar
not creating bar
creating bar
not creating bar
creating bar
not creating bar
creating bar
not creating bar
creating bar
not creating bar
deleting p
deleting p
deleting p
deleting p
deleting p
Related
I'm struggling to understand the scope and ownership of lambda captures, why does the following code work?:
#include <iostream>
struct Foo {
void setCallback(std::function<void()> f) { callback = std::move(f); }
void trigger() { callback(); }
private:
std::function<void()> callback;
};
struct Bar {
int i;
Bar(int i) : i{i} { std::cout << "bar constructed" << std::endl; }
~Bar() { std::cout << "bar destroyed" << std::endl; }
};
int main() {
Foo foo{};
{ // scope
Bar bar{1};
foo.setCallback([&bar]() { std::cout << bar.i << std::endl; });
bar.i = 2;
} //end of scope, bar gets deleted
foo.trigger();
return 0;
}
Output:
bar constructed
bar destroyed
2
Is the compiler inlining bar.i in the lambda function statically? I'm capturing by reference, what is going on?
Hello Your code does not work because bar is descoped before the lambda that captured it is executed. The lambda uses a dangling reference. Here is an updated sample that will convince you, that if it works in your example it is simply because nothing else has been allocated at the address where bar was initially stored.
#include <iostream>
#include <functional>
struct Foo {
void setCallback(std::function<void()> f) { callback = std::move(f); }
void trigger() { callback(); }
private:
std::function<void()> callback;
};
struct Bar {
int i;
Bar(int i) : i{i} { std::cout << "bar constructed" << std::endl; }
~Bar() { std::cout << "bar destroyed" << std::endl; }
};
int main() {
Foo foo{};
{ // scope
Bar bar{1};
foo.setCallback([&bar]() { std::cout << bar.i << std::endl; });
bar.i = 2;
} //end of scope, bar gets deleted
volatile int a = 5; // allocate something after bar is destroyed
foo.trigger();
return 0;
}
Now you will get:
bar constructed
bar destroyed
5
5 is the next value allocated on the stack in place of bar.
I'd like to call a few methods of classes 'A' and 'B' from the class 'Caller'. I need to use a function pointer because I want to call different methods.
My method gets called, but when I try to access a member variable from it, my program crashes ('program.exe has stopped working').
How come that happens?
#include <iostream>
using namespace std;
template <class T>
class Caller
{
typedef void (T::*myFunc)(int);
public:
Caller(T* obj, myFunc fp)
{
f = fp;
}
void invoke(int foobar)
{
(o->*f)(foobar);
}
private:
myFunc f;
T* o;
};
class A
{
public:
A() : n(0) {}
void foo(int bar)
{
cout << "A::foo called (bar = " << bar << ", n = " << n << ")" << endl; // the crash occurs here, and 'this' equals 0 at this point
}
void setNum(int num)
{
n = num;
}
private:
int n;
};
class B
{
public:
B() : n(0) {}
void fooo(int bar)
{
cout << "B::fooo called (bar = " << bar << ", n = " << n << ")" << endl; // same here if I call B::fooo first
}
void setNum(int num)
{
n = num;
}
private:
int n;
};
int main()
{
A myA;
B myB;
myA.setNum(128);
myB.setNum(256);
Caller<A> cA(&myA, &A::foo);
Caller<B> cB(&myB, &B::fooo);
cA.invoke(10);
cB.invoke(20);
return 0;
}
Thank you in advance.
EDIT : I use VS2017 and I can build my program without getting any compiler errors.
My method gets called, but when I try to access a member variable from it, my program crashes ...
Because you forgot to assign passed obj to o pointer in your Caller:
template <class T>
class Caller
{
typedef void (T::*myFunc)(int);
public:
Caller(T* obj, myFunc fp)
{
o = obj; // << == you need this!
f = fp;
}
void invoke(int foobar)
{
(o->*f)(foobar);
}
private:
myFunc f;
T* o;
};
Also, in general it's better to use member initializer lists:
Caller::Caller(T* obj, myFunc fp) : o(obj), f(fp)
{
}
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;
}
#include <iostream>
struct object1 {
object1(int v) : type(1), value(v) {}
int type;
int value;
};
struct object2 {
object2(int v) : type(2), value(v) {}
int type;
int value;
};
template <typename HeaderType>
void foo(HeaderType * hdr) {
std::cout << "foo called with type " << hdr->type << " and value " << hdr->value << std::endl;
}
// this function doesn't work
template <typename HandlerType>
void dispatch(int type, int val, HandlerType handler) {
if (type == 1) {
object1 h(val);
handler(&h);
} else {
object2 h(val);
handler(&h);
}
}
int main() {
int type = 1;
int val = 1;
// this part works
if (type == 1) {
object1 h(val);
foo(&h);
} else {
object2 h(val);
foo(&h);
}
// trying to replicate the above behavior in a more abstract way,
// ideally via a function call of the following sort
//
// dispatch(type, val, ..foo..? );
}
The above program takes an input value, uses it to decide what type of object to create, then calls a function foo with a pointer to that object.
Question: Is it possible to create this sort of abstraction where the caller of dispatch doesn't know the exact types that foo will be called with but the dispatch function doesn't know the specific function that is going to be called?
With
template <typename HandlerType>
void dispatch(int type, int val, HandlerType handler) {
if (type == 1) {
object1 h1(val);
handler(&h1);
} else {
object2 h2(val);
handler(&h2);
}
}
All branches should be valid, so handler(&h1) and handler(&h2) should be valid calls.
For that, handler may be a generic lambda (since C++14) as suggested in comment:
dispatch(type, val, [](auto a) {return foo(a);} );
or you may create your own functor:
struct foo_caller
{
template <typename HeaderType>
void operator () (const HeaderType* hdr) const {
std::cout << "foo called with type " << hdr->type << " and value " << hdr->value << std::endl;
}
};
And then call it:
dispatch(type, val, foo_caller());
My use is pretty complicated. I have a bunch of objs and they are all passed around by ptr (not reference or value unless its an enum which is byval). At a specific point in time i like to call CheckMembers() which will check if each member has been set or is null. By default i cant make it all null because i wouldnt know if i set it to null or if it is still null bc i havent touch it since the ctor.
To assign a variable i still need the syntax to be the normal var = p; var->member = new Type;. I generate all the classes/members. So my question is how can i implement a property like feature where i can detect if the value has been set or left as the default?
I am thinking maybe i can use C++ with CLR/.NET http://msdn.microsoft.com/en-us/library/z974bes2.aspx but i never used it before and have no idea how well it will work and what might break in my C++ prj (it uses rtti, templates, etc).
Reality (edit): this proved to be tricky, but the following code should handle your requirements. It uses a simple counter in the base class. The counter is incremented once for every property you wish to track, and then decremented once for every property that is set. The checkMembers() function only has to verify that the counter is equal to zero. As a bonus, you could potentially report how many members were not initialized.
#include <iostream>
using namespace std;
class PropertyBase
{
public:
int * counter;
bool is_set;
};
template <typename T>
class Property : public PropertyBase
{
public:
T* ptr;
T* operator=(T* src)
{
ptr = src;
if (!is_set) { (*counter)--; is_set = true; }
return ptr;
}
T* operator->() { return ptr; }
~Property() { delete ptr; }
};
class Base
{
private:
int counter;
protected:
void TrackProperty(PropertyBase& p)
{
p.counter = &counter;
counter++;
}
public:
bool checkMembers() { return (counter == 0); }
};
class OtherObject : public Base { }; // just as an example
class MyObject : public Base
{
public:
Property<OtherObject> x;
Property<OtherObject> y;
MyObject();
};
MyObject::MyObject()
{
TrackProperty(x);
TrackProperty(y);
}
int main(int argc, char * argv[])
{
MyObject * object1 = new MyObject();
MyObject * object2 = new MyObject();
object1->x = new OtherObject();
object1->y = new OtherObject();
cout << object1->checkMembers() << endl; // true
cout << object2->checkMembers() << endl; // false
delete object1;
delete object2;
return 0;
}
There are a number of ways to do this, with varying tradeoffs in terms of space overhead. For example, here's one option:
#include <iostream>
template<typename T, typename OuterClass>
class Property
{
public:
typedef void (OuterClass::*setter)(const T &value);
typedef T &value_type;
typedef const T &const_type;
private:
setter set_;
T &ref_;
OuterClass *parent_;
public:
operator value_type() { return ref_; }
operator const_type() const { return ref_; }
Property<T, OuterClass> &operator=(const T &value)
{
(parent_->*set_)(value);
return *this;
}
Property(T &ref, OuterClass *parent, setter setfunc)
: set_(setfunc), ref_(ref), parent_(parent)
{ }
};
struct demo {
private:
int val_p;
void set_val(const int &newval) {
std::cout << "New value: " << newval << std::endl;
val_p = newval;
}
public:
Property<int, demo> val;
demo()
: val(val_p, this, &demo::set_val)
{ }
};
int main() {
demo d;
d.val = 42;
std::cout << "Value is: " << d.val << std::endl;
return 0;
}
It's possible to get less overhead (this has up to 4 * sizeof(void*) bytes overhead) using template accessors - here's another example:
#include <iostream>
template<typename T, typename ParentType, typename AccessTraits>
class Property
{
private:
ParentType *get_parent()
{
return (ParentType *)((char *)this - AccessTraits::get_offset());
}
public:
operator T &() { return AccessTraits::get(get_parent()); }
operator T() { return AccessTraits::get(get_parent()); }
operator const T &() { return AccessTraits::get(get_parent()); }
Property &operator =(const T &value) {
AccessTraits::set(get_parent(), value);
return *this;
}
};
#define DECL_PROPERTY(ClassName, ValueType, MemberName, TraitsName) \
struct MemberName##__Detail : public TraitsName { \
static ptrdiff_t get_offset() { return offsetof(ClassName, MemberName); }; \
}; \
Property<ValueType, ClassName, MemberName##__Detail> MemberName;
struct demo {
private:
int val_;
struct AccessTraits {
static int get(demo *parent) {
return parent->val_;
}
static void set(demo *parent, int newval) {
std::cout << "New value: " << newval << std::endl;
parent->val_ = newval;
}
};
public:
DECL_PROPERTY(demo, int, val, AccessTraits)
demo()
{ val_ = 0; }
};
int main() {
demo d;
d.val = 42;
std::cout << "Value is: " << (int)d.val << std::endl;
return 0;
}
This only consumes one byte for the property struct itself; however, it relies on unportable offsetof() behavior (you're not technically allowed to use it on non-POD structures). For a more portable approach, you could stash just the this pointer of the parent class in a member variable.
Note that both classes are just barely enough to demonstrate the technique - you'll want to overload operator* and operator->, etc, as well.
Here's my temporary alternative. One that doesn't ask for constructor parameters.
#include <iostream>
#include <cassert>
using namespace std;
template <class T>
class Property
{
bool isSet;
T v;
Property(Property&p) { }
public:
Property() { isSet=0; }
T operator=(T src) { v = src; isSet = 1; return v; }
operator T() const { assert(isSet); return v; }
bool is_set() { return isSet; }
};
class SomeType {};
enum SomeType2 { none, a, b};
class MyObject
{
public:
Property<SomeType*> x;
Property<SomeType2> y;
//This should be generated. //Consider generating ((T)x)->checkMembers() when type is a pointer
bool checkMembers() { return x.is_set() && y.is_set(); }
};
int main(int argc, char * argv[])
{
MyObject* p = new MyObject();
p->x = new SomeType;
cout << p->checkMembers() << endl; // false
p->y = a;
cout << p->checkMembers() << endl; // true
delete p->x;
delete p;
}