I have a peculiar problem. I want to create classes with variable length arrays in them. I don't want to allocate the arrays on the heap for the reasons of locality (the code slows down by a factor of 2 when I do). I don't want to use a virtual function because I don't want to pay for a function call. The following code works (on my compiler/platform), but with a caveat.
include <iostream>
include <boost/array.hpp>
struct Base
{
Base(size_t s):
size(s) {}
int& up(size_t i) { return *(reinterpret_cast<int*>((&size) + 1) + i); }
size_t size;
};
template<size_t sz>
struct Derived: public Base
{
boost::array<int, sz> data;
Derived(): Base(sz) {}
};
int main()
{
Derived<5> d5;
d5.data[2] = 1234;
Base* b = &d5;
std::cout << b->up(2) << std::endl;
}
This is incredibly ugly; the reinterpret_cast<...> is a red flag. Moreover, the caveat is that this fails if I change size_t to, say, short unsigned (I guess the compiler pads the class).
So the question is: is there a way to make this portable? Is there a way to determine from Base where the first member variable will sit in its derived class?
Just an idea that came to my mind: let the Derived constructor store a pointer to its data inside a Base member.
struct Base
{
protected:
size_t size;
int * array;
Base(size_t s, int * arr):
size(s), array(arr)
{ }
public:
int& up(size_t i) { return array[i]; }
size_t getSize() { return size; }
};
template<size_t sz>
struct Derived: public Base
{
std::array<int, sz> data;
Derived():
Base(sz, &data[0])
{ }
};
int main()
{
Derived<5> d5;
d5.data[2] = 1234;
Base* b = &d5;
std::cout << b->up(2) << std::endl;
}
From your comment, it sounds like something like this might suffice:
#include <cstddef>
#include <array>
#include <algorithm>
template <typename T>
struct ArrayBase
{
typedef T type;
type & operator[](std::size_t i) { return buf[i]; }
type const & operator[](std::size_t i) const { return buf[i]; }
protected:
ArrayBase(type * p) : buf(p) { }
private:
type * buf;
};
template <typename T, std::size_t N>
struct Array : ArrayBase<T>
{
Array()
: ArrayBase<T>(a.data())
{
}
Array(Array const & rhs)
: ArrayBase<T>(a.data())
{
std::copy(rhs.a.begin(), rhs.a.end(), a.begin());
}
private:
std::array<T, N> a;
};
Usage:
Array<int, 5> a5;
ArrayBase<int> & b = a5;
b[2] = 11;
Array<int, 5> a52 = a5;
a52[2] = 13;
Here's a dangerous, but fast and small answer:
template<class T>
struct alloca_magic {
T* b;
int s;
alloca_magic(void* bu, int sz)
: b((T*)(bu)),s(sz)
{new(b)T[s];}
~alloca_magic()
{for(int i=0;i<s;++i)(b+i)->~T();}
operator T*() {return b;}
};
#define alloca_magic(Type,Name,Size) void* t = alloca(sizeof(Type)*Size); alloca_magic<Type> Name(t,Size);
#include <iostream>
struct test {
int data;
test() {std::cout << "ctor\n";}
~test() {std::cout << "dtor\n";}
};
void foo(int len) {
std::cout << "begin foo\n";
alloca_magic(test ,buffer,len);
for(int i=0; i<len; i++)
buffer[i].data = i;
std::cout << "end foo\n";
}
int main() {
int len;
std::cin >> len;
std::cout << "begin main\n";
alloca_magic(test ,buffer,len);
for(int i=0; i<len; i++)
buffer[i].data = i;
foo(len);
std::cout << "end main\n";
}
http://ideone.com/ccvTR results:
begin main
ctor
ctor
ctor
begin foo
ctor
ctor
ctor
end foo
dtor
dtor
dtor
end main
dtor
dtor
dtor
For windows you'll have to replace alloca with _alloca. Keep in mind that this is easily abused and broken, and if done with large numbers can cause a stack overflow. I do not recommend this for anything besides speed tests, and probably not then either.
Related
I am working with conversion operators and I an error just popped out of nowhere. C class is derived from B and has no relation with class A, however, debugger shows that when doing C* val1 = new C val1 is showed as C* {A<B>}. It also produces an error because that A in the C* pointer has a size of an unreasonable size (it gives a different size each time it is executed so I just suppose it gets a number from another application).
#include <iostream>
#include <vector>
template<typename widget_type>
class A
{
public:
std::vector<widget_type*> value;
virtual ~A() {}
void Add(widget_type* val)
{
value.push_back(val);
}
template<typename return_type>
operator A<return_type>()
{
unsigned int size = this->value.size();
std::vector<return_type*> return_value;
return_value.reserve(size);
for (unsigned int i = 0; i < size; i++)
{
return_value[i] = dynamic_cast<return_type*>(this->value[i]);
}
A<return_type> target;
target.value = return_value;
return target;
}
};
class B
{
public:
virtual ~B() {}
};
class C : public B
{
public:
void Print()
{
std::cout << "C CALL\n";
}
};
class D : public B
{
};
int main()
{
std::cout << "Start!\n";
A<C> source;
C* val1 = new C;
source.Add(val1);
A<B> target = source;
A<B>* target2 = dynamic_cast<A<B>*>(&source);
std::cout << "END\n";
}```
for (unsigned int i = 0; i < size; i++)
{
return_value[i] = dynamic_cast<return_type*>(this->value[i]);
}
You are invoking undefined behaviour by accessing return_value[i] on an empty vector.
Is there any way I can pass vector's index to an constructor of it's element?
for example:
#include <iostream>
#include <vector>
class Foo {
public:
Foo(unsigned long index) {
std::cout << index << std::endl;
}
};
int main() {
std::vector<Foo> foo;
foo.resize(2); // any way to make this work?
}
this code does of cause not work because the compiler don't know how to construct a Foo(unsigned long index), but any way I can do some tricks(for example to custom an allocator?) to make this code actually work?
You can add elements in a for loop and pass the index as an argument to their ctors like this:
// Init your vector + optionally reserve space
std::vector<Foo> foo;
const unsigned elements_to_add = 5; // or whatever number
foo.reserve(foo.size() + elements_to_add);
// foo.size() will be passed as parameter to the ctor you defined
for (std::size_t i = 0; i < elements_to_add; i++) {
foo.emplace_back(foo.size());
}
No, you will want to use std::generate() , or std::generate_n() in combination with std::back_inserter().
You can write a custom statefull allocator that will pass an index when an object is constructed.
Minimal example:
template<class T>
class Allocator {
public:
using value_type = T;
T* allocate(std::size_t n) {
return static_cast<T*>(::operator new(n * sizeof(T)));
}
void deallocate(T* p, std::size_t) noexcept {
::operator delete(p);
}
template<class... Args>
void construct(T* p, Args&&... args) {
::new(static_cast<void*>(p)) T(counter_++, std::forward<Args>(args)...);
}
void destroy(T* p) noexcept {
p->~U();
--counter_;
}
private:
std::size_t counter_ = 0;
};
Usage example:
struct Foo {
Foo(std::size_t index) {
std::cout << index << ' ';
}
Foo(std::size_t index, const Foo& other) : Foo(other) {
std::cout << index << ' ';
}
};
std::vector<Foo, Allocator<Foo>> foos1;
foos1.resize(3);
std::cout << std::endl;
std::vector<Foo, Allocator<Foo>> foos2;
foos2.resize(4);
// Output:
// 0 1 2
// 0 1 2 3
I guess there are many ways to get more or less what you want. But sooner or later, you'll probably find out that you won't need this.
Here is a possible solution:
#include <iostream>
#include <vector>
class Foo
{
inline static unsigned long _static_index = 0;
unsigned long _index;
public:
Foo() : _index(_static_index) { ++_static_index; }
auto index() const { return _index; }
static void resetIndex() { _static_index = 0; }
};
int main()
{
std::vector<Foo> foos;
Foo::resetIndex();
foos.resize(2);
for (const auto& f : foos)
std::cout << f.index() << std::endl;
return 0;
}
So, you just increment a static counter and assign it to the private member _index. This obviously has its limitations. For instance, say you create 3 instances of Foo before filling your vector of Foos, then foos[0].index() would return 3 instead of 0. So, before filling foos, you would need to reset the _static_index.
I have written a small piece of code where I am able to call setter and getter functions packed within a functoid using mem_fun templates.
I now would like to use this approach on top of a class hierarchy where every class might have getter and setter which can be registered as pair within a vector or array to be able to call the getter and setter if needed. GUIObject and GUICompositeObject are example classes out of the described class hierarchy.
The bound_mem_fun_t for the objects have unfortunately different types and thats the reason I don't know how to integrate them into an array/vector of pointers to the functors.
In c++11 I would use std::function. Is there a way to emulate this in c++98?
Because our compiler support only c++98 I cannot use the new features of c++11 or c++14. Also boost is not allowed.
#include <functional>
class GUIObject
{
int m_Alpha;
public:
void SetAlpha(int a) { m_Alpha = a;};
int GetAlpha() {return m_Alpha;};
};
class GUICompositeObject: public GUIObject
{
int m_NumOfChilds;
public:
void SetNumOfChilds(int NumOfChilds) { m_NumOfChilds = NumOfChilds;};
int GetNumOfChilds() {return m_NumOfChilds;};
};
template<typename T>
struct bound_mem_fun_t
{
bound_mem_fun_t(std::mem_fun_t<int, T> GetFunc, std::mem_fun1_t<void, T, int> SetFunc, T* o) :
m_GetFunc(GetFunc), m_SetFunc(SetFunc), obj(o) { } ;
int operator()() { return m_GetFunc(obj); } ;
void operator()(int i) { m_SetFunc(obj, i); } ;
std::mem_fun_t<int, T> m_GetFunc;
std::mem_fun1_t<void, T, int> m_SetFunc;
T* obj;
};
int main()
{
GUIObject kGUIObject;
GUICompositeObject kCompObj;
bound_mem_fun_t<GUIObject> GUIObjectFunc(std::mem_fun(&GUIObject::GetAlpha), std::mem_fun(&GUIObject::SetAlpha), &kGUIObject);
GUIObjectFunc(17);
int ii = GUIObjectFunc();
bound_mem_fun_t<GUICompositeObject> GUICompObjectFunc(std::mem_fun(&GUICompositeObject::GetNumOfChilds), std::mem_fun(&GUICompositeObject::SetNumOfChilds), &kCompObj);
GUICompObjectFunc(17);
int iChilds = GUICompObjectFunc();
return 0;
}
Here is the complete solution after #filmors answer:
#include <functional>
#include <vector>
#include <iostream>
class GUIObject
{
int m_Alpha;
public:
void SetAlpha(int a) { m_Alpha = a;};
int GetAlpha() {return m_Alpha;};
};
class GUICompositeObject: public GUIObject
{
int m_NumOfChilds;
public:
void SetNumOfChilds(int NumOfChilds) { m_NumOfChilds = NumOfChilds;};
int GetNumOfChilds() {return m_NumOfChilds;};
};
struct bound_mem_fun_base
{
virtual int operator()() =0;
virtual void operator()(int) =0;
};
template<typename T>
struct bound_mem_fun_t : public bound_mem_fun_base
{
bound_mem_fun_t(std::mem_fun_t<int, T> GetFunc, std::mem_fun1_t<void, T, int> SetFunc, T* o) :
m_GetFunc(GetFunc), m_SetFunc(SetFunc), obj(o) { } ;
virtual int operator()() { return m_GetFunc(obj); } ;
virtual void operator()(int i) { m_SetFunc(obj, i); } ;
std::mem_fun_t<int, T> m_GetFunc;
std::mem_fun1_t<void, T, int> m_SetFunc;
T* obj;
};
template<typename T> bound_mem_fun_t<T>* make_setter(std::mem_fun_t<int, T> GetFunc, std::mem_fun1_t<void, T, int> SetFunc, T* o)
{
return new bound_mem_fun_t<T> (GetFunc, SetFunc, o);
}
int main()
{
GUIObject kGUIObject;
GUICompositeObject kCompObj;
std::vector<bound_mem_fun_base*> kBoundVector;
kBoundVector.push_back(new bound_mem_fun_t<GUIObject> (std::mem_fun(&GUIObject::GetAlpha), std::mem_fun(&GUIObject::SetAlpha), &kGUIObject));
kBoundVector.push_back(new bound_mem_fun_t<GUICompositeObject> (std::mem_fun(&GUICompositeObject::GetNumOfChilds), std::mem_fun(&GUICompositeObject::SetNumOfChilds), &kCompObj));
kBoundVector.push_back(make_setter<GUIObject> (std::mem_fun(&GUIObject::GetAlpha), std::mem_fun(&GUIObject::SetAlpha), &kGUIObject));
kBoundVector.push_back(make_setter<GUICompositeObject> (std::mem_fun(&GUICompositeObject::GetNumOfChilds), std::mem_fun(&GUICompositeObject::SetNumOfChilds), &kCompObj));
for (int i = 0; i < 4 ; i++)
{
(*kBoundVector[i])(i*10);
int res = (*kBoundVector[i])();
std::cout << "Getter result " << res << "\n";
}
return 0;
}
Unfortunately the make_setter function does not really shorten the creation of the functor. Any ideas will be welcome.
Just give your bound_mem_fun_t<T> a common base class and use dynamic dispatch to solve your problem:
struct bound_mem_fun_base {
virtual int operator()() = 0;
virtual void operator()(int) = 0;
};
template <typename T>
struct bound_mem_fun_t : bound_mem_fun_t ...
Then you can keep pointers to bound_mem_fun_base in your vector and call the elements as (*v[0])().
Also, TR1 does contain std::tr1::function, is that available?
First a remark on std::function from c++11: That will not solve your problem, because you need an already bounded function pointer. This pointer must be bound to your object. I believe what you need is an own implementation to std::bind.
I started only a very! small Binder class which is hopefully a starting point for your needs. If you need to have template parameter lists in older c++ versions, take a look for loki. http://loki-lib.sourceforge.net/
As a hint I can give you a short example of what i did:
class A
{
private:
int val;
public:
A(int i): val(i) {}
void Do(int i) { std::cout << "A " << val<< " " << i << std::endl; }
};
class B
{
private:
int val;
public:
B(int i): val(i){}
void Go(int i) { std::cout << "B " << val << " " << i << std::endl; }
};
class Base
{
public:
virtual void operator()(int i)=0;
};
template <typename T>
class Binder: public Base
{
void (T::*fnct)(int);
T* obj;
public:
Binder( void(T::*_fnct)(int), T*_obj):fnct(_fnct),obj(_obj){}
void operator()(int i)
{
(obj->*fnct)(i);
}
};
int main()
{
A a(100);
B b(200);
// c++11 usage for this example
//std::function<void(int)> af= std::bind( &A::Do, &a, std::placeholders::_1);
//af(1);
// hand crafted solution
Base* actions[2];
actions[0]= new Binder<A>( &A::Do, &a);
actions[1]= new Binder<B>( &B::Go, &b);
actions[0]->operator()(55);
actions[1]->operator()(77);
}
I want to write a function, to which an array is passed, and have a possibility to use range for inside. I managed to do it for a fixed-size array only.
void print(unsigned (&arr)[11]){
for (unsigned val : arr)
cout << val << ' ';
cout << endl;
}
void main() {
unsigned arr[11] = {};
print(arr);
}
How to do it for variable-size arrays? Thx.
For other sizes known at compile time:
template <unsigned N>
void print(unsigned (&arr)[N]){
for (unsigned val : arr)
cout << val << ' ';
cout << endl;
}
int main() {
unsigned arr[11] = {};
unsigned arr2[12] = {};
print(arr);
print(arr2);
return 0;
}
My preferred solution is to do a bit of type erasure here.
template<typename T>
struct contig_range_view {
// leave these public. Why not?
T const* b = nullptr;
T const* e = nullptr;
// this means you support for( T x : me ) loops:
T const* begin() const { return b; }
T const* end() const { return e; }
// While we are here, lets support [] indexing and .size(), because:
T const& operator[](unsigned i) const { return b[i]; }
std::size_t size() const { return e-b; }
// default copy/construct/assign:
contig_range_view() = default;
contig_range_view(contig_range_view const&) = default;
contig_range_view& operator=(contig_range_view const&) = default;
// conversion from [] style arrays, std::arrays, and std::vector (implicit):
template<unsigned N>
contig_range_view( const T(&arr)[N] ):b(arr), e(arr+N) {}
template<unsigned N>
contig_range_view( std::array<T, N> const&arr ):b(&arr[0]), e(b+N) {}
template<typename A>
contig_range_view( std::vector<T, A> const& v ):b(v.data()), e(v.data()+v.size()) {}
};
// example use. Far less terrifying than the above, isn't it?
void print( contig_range_view<unsigned> arr ) {
for (unsigned x : arr) {
std::cout << x << ",";
}
std::cout << "\n";
}
this has the advantage of allowing the implementation of print to live in a different compilation unit than its interface or where it is called.
And it supports std::array and std::vector for free (as they have identical binary layouts to [] style arrays, why not?)
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;
}