C++ Vector of template class, Polymorphism - c++

Every time that I create a object, I store the pointer of that object in a vector, which is a static member of the class of the object, in order to monitor its state, something like this:
class A {
private:
static std::vector<A *> as;
STATE state = NONE; //<- enum
void doSomething();
public:
A() {
as.push_back(this);
}
static void monitor() {
auto end = as.end();
for (auto obj = as.begin(); obj != end; obj++) {
switch ((*obj)->state) {
//process it
(*obj)->doSomething();
}
}
}
}
//// recurrent call in other part of the program or even in other thread
A::monitor();
The above code is obviously incomplete, lacks an appropriately destructor, to remove the pointer of the vector that is being deleted.
the problem now is that I have to do the same with a template class
template <typename T>
class A {
void doSomething(); //<--independent, no template
....
}
Is there any way to do the same?, applying the independent type method "doSomething()" for every object?
If the function "doSomething()" was dependent type, there would be a way to accomplish the same?

You can do the same:
template <typename T>
class A {
private:
static std::vector<A<T>*> as;
STATE state = NONE; //<- enum
void doSomething()
public:
A() { as.push_back(this); }
static void monitor() {
auto end = as.end();
for (auto obj = as.begin(); obj != end; obj++) {
switch ((*obj)->state) {
//process it
(*obj)->doSomething();
}
}
}
}
template <typename T>
std::vector<A<T>*> as;
You just have to call
A<MyType>::monitor();

Related

Is it possible for a class object to keep a static pointer to itself?

I know this sounds like a weird thing to want, but I guess I have my reasons. I can do:
#include <string>
#include <iostream>
struct Shark
{
template <auto* static_ptr_to_self>
void whatIsMyAddress() {
std::cout << std::string("My address is ") + std::to_string((uintptr_t)static_ptr_to_self);
}
};
Shark shark;
int main()
{
shark.whatIsMyAddress<&shark>();
return 0;
}
But is there a way to achieve something like this without passing in the pointer to the function? For example can the object itself hold a pointer, resolved at compile-time, not a runtime pointer, to itself? My instinct is no because when the object is created it hasn't been declared yet. But is there some way to achieve this? If there isn't through passing the pointer as a template argument then is there a way with a constexpr member pointer?
Edit: Just to explain my question better:
struct ResourceMngr
{
void IveBeenCopied(const Handle& handle);
int referenceCountTracker[256];
};
struct Handle
{
int ID;
Handle(const Handle& other) { dynamicPtrToManager->IveBeenCopied(*this); }
ResourceMngr* dynamicPtrToManager;
};
void ResourceMngr::IveBeenCopied(const Handle& handle)
{
++referenceCountTracker[handle.ID];
}
So each handle has a pointer to let whatever is managing the resource know of 'stuff'. So now I can get rid of the pointer in handle, which has the effect of eliminating the pointer lookup (because it's constexpr) and also eliminating a pointer from each handle, by doing this:
struct ResourceMngr
{
void IveBeenCopied(const auto& handle);
int referenceCountTracker[256];
};
template <auto* static_ptr_to_manager>
struct Handle
{
int ID;
Handle() {}
Handle(const Handle& other) { static_ptr_to_manager->IveBeenCopied(*this); }
//ResourceMngr* dynamicPtrToManager; // No longer needed
};
void ResourceMngr::IveBeenCopied(const auto& handle) { ++referenceCountTracker[handle.ID]; }
ResourceMngr bufferManager;
int main()
{
Handle<&bufferManager> handle1;
Handle<&bufferManager> handle2 = handle1;
// No pointer members in each handle,
// no runtime lookup of pointers
}
And I can get a handle from a resource manager like:
template <auto* static_ptr_to_manager>
struct Handle
{
int ID;
Handle() {}
Handle(const Handle& other) {
//static_ptr_to_manager->IveBeenCopied(*this);
}
};
struct ResourceMngr
{
template <auto* static_ptr_to_self_type>
Handle<static_ptr_to_self_type> getHandleToAResourceOrObject()
{
return Handle<static_ptr_to_self_type>();
}
};
ResourceMngr bufferManager;
int main()
{
Handle<&bufferManager> handle = bufferManager.getHandleToAResourceOrObject<&bufferManager>();
// Here I have to specify in the function call
//which manager I'm referring to.
// The bufferManager couldn't use the this pointer as
//it's not constexpr and can't be used
// in template arguments
}

creating type vector in c++

I have several classes that each of them has an ID and the Id is passed to the class as a template parameter:
typedef class1<1> baseClass;
typedef class2<2> baseClass;
typedef class<100> baseClass;
Now I need a map so if I can associate 1 with Class1 and 2 with Class2 and so on.
How can I create such vector? I am working on a header only library, so it should be a header only definition.
I am looking something that do the same thing that this code would do (if someone can compile it!):
std::map<int,Type> getMap()
{
std::map<int,Type> output;
output.add(1,class1);
output.add(2,class2);
output.add(100,class100);
}
The idea is that when I get as input 1, I create a class1 and when I receive 2, I create class2.
Any suggestion is very appreciated.
using this data, then I can write a function like this:
void consume(class1 c)
{
// do something interesting with c
}
void consume(class2 c)
{
// do something interesting with c
}
void consume(class3 c)
{
// do something interesting with c
}
void consume(int id,void * buffer)
{
auto map=getMap();
auto data= new map[id](buffer); // assuming that this line create a class based on map, so the map provide the type that it should be created and then this line create that class and pass buffer to it.
consume(data);
}
As a sketch:
class BaseClass { virtual ~BaseClass() = default; };
template<std::size_t I>
class SubClass : public BaseClass {};
namespace detail {
template<std::size_t I>
std::unique_ptr<BaseClass> makeSubClass() { return { new SubClass<I> }; }
template<std::size_t... Is>
std::vector<std::unique_ptr<BaseClass>(*)> makeFactory(std::index_sequence<Is...>)
{ return { makeSubclass<Is>... }; }
}
std::vector<std::unique_ptr<BaseClass>(*)> factory = detail::makeFactory(std::make_index_sequence<100>{});
We populate the vector by expanding a parameter pack, so we don't have to write out all 100 instantiations by hand. This gives you Subclass<0> at factory[0], Subclass<1> at factory[1], etc. up to Subclass<99> at factory[99].
If I understand correctly you want a map to create different types according to a given number.
If that is so, then the code should look something like this:
class Base
{
};
template <int number>
class Type : public Base
{
public:
Type()
{
std::cout << "type is " << number << std::endl;
}
};
using Type1 = Type<1>;
using Type2 = Type<2>;
using Type3 = Type<3>;
using CreateFunction = std::function<Base*()>;
std::map<int, CreateFunction> creators;
int main()
{
creators[1] = []() -> Base* { return new Type1(); };
creators[2] = []() -> Base* { return new Type2(); };
creators[3] = []() -> Base* { return new Type3(); };
std::vector<Base*> vector;
vector.push_back(creators[1]());
vector.push_back(creators[2]());
vector.push_back(creators[3]());
}
output:
type is 1
type is 2
type is 3
If you need only to create object, it would be enough to implement template creator function like:
template<int ID>
Base<ID> Create()
{
return Base<ID>();
}
And then use it:
auto obj1 = Create<1>();
auto obj2 = Create<2>();
// etc
Working example: https://ideone.com/urh7h6
Due to C++ being a statically-typed language, you may choose to either have arbitrary types that do a fixed set of things or have a fixed set of types do arbitrary things, but not both.
Such limitations is embodied by std::function and std::variant. std::function can have arbitrary types call operator() with a fixed signature, and std::variant can have arbitrary functions visit the fixed set of types.
Since you already said the types may be arbitrary, you may only have a fixed set of things you can do with such a type (e.g. consume). The simplest way is to delegate the hard work to std::function
struct Type
{
template<typename T>
Type(T&& t)
: f{[t = std::forward<T>(t)]() mutable { consume(t); }} {}
std::function<void()> f;
};
void consume(Type& t)
{
t.f();
}
What you are looking for is either the Stategy pattern:
#include <iostream>
#include <memory>
#include <string>
#include <vector>
class A {
public:
A() {}
virtual void doIt() {};
};
class Aa : public A {
public:
Aa() {}
virtual void doIt() {
std::cout << "do it the Aa way" << std::endl;
}
};
class Ab : public A {
public:
Ab() {}
virtual void doIt() {
std::cout << "do it the Ab way" << std::endl;
}
};
class Concrete {
public:
Concrete(std::string const& type) {
if (type == ("Aa")) {
_a.reset(new Aa());
} else if (type == "Ab") {
_a.reset(new Ab());
}
}
void doIt () const {
_a->doIt();
}
private:
std::unique_ptr<A> _a;
};
int main() {
std::vector<Concrete> vc;
vc.push_back(Concrete("Aa"));
vc.push_back(Concrete("Ab"));
for (auto const& i : vc) {
i.doIt();
}
return 0;
}
Will output:
do it the Aa way
do it the Ab way

Storage of function pointer in polymorphic class without explicit template specialization

I am trying to create a helper class to abstract invoking function pointers. With feedback from others on SO, I am using a polymorphic class to achieve this (shown below). Templates are also used to reduce code duplication.
typedef void(*PFNFOO1) (int);
typedef void(*PFNFOO2) (double);
typedef void(*PFNBAR1) (long);
typedef void(*PFNBAR2) (float);
typedef struct FOO_TABLE
{
PFNFOO1 pfnFoo1;
PFNFOO2 pfnFoo2;
} FOO_TABLE;
typedef struct BAR_TABLE
{
PFNBAR1 pfnBar1;
PFNBAR2 pfnBar2;
} BAR_TABLE;
enum TABLE_TYPE
{
TYPE_FOO = 0,
TYPE_BAR = 1,
};
template <typename T>
class FooBarImpl : public FooBarBase
{
public:
// GetFunc is created to centralize needed validation before function is invoked
void* GetFunc(size_t funcOffset)
{
// do some validation
return reinterpret_cast<void*>(m_FooBarTable + funcOffset);
}
void* GetpfnFoo1() { return GetFunc(offsetof(T, pfnFoo1)); }
void* GetpfnFoo2() { return GetFunc(offsetof(T, pfnFoo2)); }
void* GetpfnBar1() { return GetFunc(offsetof(T, pfnBar1)); }
void* GetpfnBar2() { return GetFunc(offsetof(T, pfnBar2)); }
T* m_FooBarTable;
};
class FooBarBase
{
public:
static FooBarBase* CreateFooBar(TABLE_TYPE tableType)
{
switch(tableType)
{
case (TYPE_FOO) :
{
return new FooBarImpl<FOO_TABLE>();
}
break;
case (TYPE_BAR) :
{
return new FooBarImpl<BAR_TABLE>();
}
break;
}
}
virtual void* GetpfnFoo1() = 0;
virtual void* GetpfnFoo2() = 0;
virtual void* GetpfnBar1() = 0;
virtual void* GetpfnBar2() = 0;
};
int _tmain(int argc, _TCHAR* argv[])
{
{
FooBarBase *pFooBar = FooBarBase::CreateFooBar(TYPE_FOO);
// Initialize Foo table
auto p = reinterpret_cast<PFNFOO1>(pFooBar->GetpfnFoo1());
int parameter = 1;
p(parameter);
}
{
FooBarBase *pFooBar = FooBarBase::CreateFooBar(TYPE_FOO);
// Initialize Bar table
auto p = reinterpret_cast<PFNBAR2>(pFooBar->GetpfnBar2());
float parameter = 1.0f;
p(parameter);
}
return 0;
}
This is currently giving me complication errors as "C2039: 'pfnBar1' : is not a member of 'FOO_TABLE'" which makes sense because one of the implicit template specialization will try to do "offsetof(FOO_TABLE, pfnBar1)," which isn't allowed. I have two questions. First, I am wondering what's the best way to address this error. I think I can possibly address this by providing explicit template specializations for FooBarImpl and FooBarImpl, but I'd like to avoid doing that because it means that if I were to add a new table type later, I'd have to add another specialization. Also, it increases code duplication. Therefore, if there's a way to fix this issue without explicit template specialization, please let m know.
For my second question, if explicit template specialization cannot be avoided, I have also tried this:
class FooBarBase;
template <typename T>
class FooBarImpl : public FooBarBase
{
};
template <>
class FooBarImpl<FOO_TABLE> : public FooBarBase
{
public:
typedef FOO_TABLE T;
// GetFunc is created to centralize needed validation before function is invoked
void* GetFunc(size_t funcOffset)
{
// do some validation
return reinterpret_cast<void*>(m_FooBarTable + funcOffset);
}
void* GetpfnFoo1() { return GetFunc(offsetof(T, pfnFoo1)); }
void* GetpfnFoo2() { return GetFunc(offsetof(T, pfnFoo2)); }
T* m_FooBarTable;
};
template<>
class FooBarImpl<BAR_TABLE> : public FooBarBase
{
public:
typedef BAR_TABLE T;
// GetFunc is created to centralize needed validation before function is invoked
void* GetFunc(size_t funcOffset)
{
// do some validation
return reinterpret_cast<void*>(m_FooBarTable + funcOffset);
}
void* GetpfnBar1() { return GetFunc(offsetof(T, pfnBar1)); }
void* GetpfnBar2() { return GetFunc(offsetof(T, pfnBar2)); }
T* m_FooBarTable;
};
But for some reason, I keep getting this error "error C2504: 'FooBarBase' : base class undefined" even if it was working fine before I specialized the templates.
If anyone has ideas about these 2 questions, I'd really appreciate your feedback. Thanks.

event system optimization

If I have these declarations and definitions:
enum Events
{
INIT,
RENDER
};
struct EventBase
{
typedef void (EventBase::*event_callback_type)();
~EventBase() {}
virtual void init() { assert(0); }
virtual void render() { assert(0); }
};
template <enum Events>
struct EventTraits
{
static EventBase::event_callback_type const event_callback;
};
// in a .cpp file
template <>
EventBase::event_callback_type const
EventTraits<INIT>::event_callback(
&EventBase::init);
template <>
EventBase::event_callback_type const
EventTraits<RENDER>::event_callback(
&EventBase::render);
// in another class *i are pointers to objects that inherit EventBase
template <enum Events event>
inline void EventNotifier::notify()
{
for (events_type::const_iterator i(event_handlers[event].begin());
i != event_handlers[event].begin() + num_event_handlers[event];
++i)
{
((*i)->*EventTraits<event>::event_callback)();
if ((*i)->num_event_handlers[event])
{
(*i)->notify<event>();
}
// else do nothing
}
}
Say, that the event RENDER needs fastest possible handling, do you think it is worthwhile to do a member template specialization:
template <>
inline void EventNotifier::notify<RENDER>()
{
for (events_type::const_iterator i(event_handlers[RENDER].begin());
i != event_handlers[RENDER].begin() + num_event_handlers[RENDER];
++i)
{
(*i)->render();
if ((*i)->num_event_handlers[RENDER])
{
(*i)->notify<RENDER>();
}
// else do nothing
}
}
This would not require the fetching of a static pointer to a member function. Or perhaps I should do this:
template <enum Events>
struct EventTraits
{
static EventBase::event_callback_type event_callback();
};
And specialize the struct template?
Just additional 5 cents. EventNotifier::notify() looks completely thread-unsafe. Futhermore, if any event handler generates new event bad things can happen. I suggest doing notification this way (C++ 11, just don't know all of your types):
template <> inline void EventNotifier::notify<RENDER>()
{
decltype(event_handlers[RENDER]) local;
decltype(num_event_handlers[RENDER]) local_num;
{
std::lock_guard<std::mutex> guard(my_mutex);
local = event_handlers[RENDER];
local_num = num_event_handlers[RENDER];
}
for (events_type::const_iterator i(local.begin()); i != local.begin() + local_num; ++i)
{
(*i)->render();
if ((*i)->num_event_handlers[RENDER]) (*i)->notify<RENDER>();
}
}
The member specialisation won't make any difference in it's current form as the code you have written in identical to the code the compiler will generate for you.
Here's a small improvement:
template <enum Events event>
inline void EventNotifier::notify()
{
for (events_type::const_iterator i(event_handlers[event].begin()),
end (event_handlers[event].begin() + num_event_handlers[event]);
i != end; ++i)
{
((*i)->*EventTraits<event>::event_callback)();
if ((*i)->num_event_handlers[event])
{
(*i)->notify<event>();
}
// else do nothing
}
}

Remove the defines in this safeguard mutex example

-edit- i cant experiment ATM but will tonight. I am thinking maybe a typedef can be used to hold mut and can be used to declare a var. But my initial thought is typedefs don't play nice with templates so i'll have to check later tonight (for now, to class)
I was looking at this piece of code shown below and i was wondering how it might be possible to implement without using defines.
Since I cant compile the code (i don't have any mutex/multithreading libs currently installed) i'll just look at the code and think it out.
It seems like one can completely implement PROTECTED_WITH by inheriting a template class. The problem is now PROTECTED_MEMBER. It uses a name with ## to create a variable. This isnt much of a problem because we create a class which holds the variable with the () operator to make it appear as a function. However accessing is_held() the problem as i would like not to pass this or mut_ in.
My gut says with out of the box thinking its possible to solve this without defines and without passing in to each variable a this, function ptr or reference. I'll allow everyone to cheat and use c++0x features.
template<typename Mutex>
class TestableMutex {
public:
void lock() { m.lock(); id = this_thread::get_id(); }
void unlock() { id = 0; m.unlock(); }
bool try_lock() { bool b = m.try_lock();
if( b ) id = this_thread::get_id();
return b; }
bool is_held() { return id == this_thread::get_id(); }
private:
Mutex m;
atomic<thread::id> id;
// for recursive mutexes, add a count
};
#define PROTECTED_WITH(MutType) \
public: void lock() { mut_.lock(); } \
public: bool try_lock() { return mut_.try_lock(); } \
public: void unlock() { mut_.unlock(); } \
private: TestableMutex<MutType> mut_;
#define PROTECTED_MEMBER(Type,name) \
public: Type& name() { assert(mut_.is_held()); return name##_; } \
private: Type name##_;
struct MyData {
PROTECTED_WITH( some_mutex_type );
PROTECTED_MEMBER( vector<int>, v );
PROTECTED_MEMBER( Widget*, w );
};
You can use an explicit specialization containing using declarations to list the objects protected by the mutex. Then use a base class to "pass" the access out to the user via operator->, so object->member (with object not being a pointer) performs the mutex assertion.
This is easier done than said:
// Imagine that the members of this class must be locked by the mutex.
class a : public expose_locked_by_arrow< a > {
protected:
int i;
void f();
};
// Declare which members are conditionally locked. Pretty simple and idiomatic.
template<>
struct member_expose< a > : a {
using a::i;
using a::f;
};
#include <iostream>
// Access mutex-locked members with ->
int main() {
a x;
x->i = 5;
a const y( x );
std::cout << y->i << '\n';
}
The library code:
// This template is specialized for each mutex protection client.
template< class >
struct member_expose;
// Base class provides mutex; parameter is derived class (CRTP).
template< class c >
struct expose_locked_by_arrow {
member_expose< c > *
operator->() {
assert ( expose_lock_mutex.is_held() );
return static_cast< member_expose< c > * >( this );
}
member_expose< c > const *
operator->() const {
assert ( expose_lock_mutex.is_held() );
return static_cast< member_expose< c > const * >( this );
}
expose_locked_by_arrow( mutex const &m = mutex() )
: expose_lock_mutex( m ) {}
protected:
mutex expose_lock_mutex;
};
See it run.
The #defines aren't providing any protection as such, rather they are just reducing the amount of typing you'd have to do (in turn, they make sure all the "protected" members have the proper code in place).
There isn't a way that I am aware of to avoid having to put the checks into each getter function - and locking the whole object, as they are returning references to data stored within the protected object.
If however, they could all be returned by value (or not returning anything at all), then you could use a container that locks everything using a proxy object, something like the following (this could probably be done better, i've just quickly hacked it together):
#include <iostream>
struct Mutex
{
void lock()
{
std::cout << "Mutex::lock" << std::endl;
}
void unlock()
{
std::cout << "Mutex::unlock" << std::endl;
}
};
template <class Object>
class ThreadSafeObject
{
mutable Mutex d_mutex;
Object d_object;
public:
struct Proxy
{
mutable Mutex *d_mutex;
Object *d_object;
Proxy(Mutex *mutex, Object *object)
: d_mutex(mutex)
, d_object(object)
{
d_mutex->lock();
}
Proxy(const Proxy& proxy)
: d_mutex(proxy.d_mutex)
, d_object(proxy.d_object)
{
proxy.d_mutex = NULL;
}
~Proxy()
{
if (d_mutex)
{
d_mutex->unlock();
}
}
Object *operator->()
{
return d_object;
}
};
struct ConstProxy
{
mutable Mutex *d_mutex;
const Object *d_object;
ConstProxy(Mutex *mutex, const Object *object)
: d_mutex(mutex)
, d_object(object)
{
d_mutex->lock();
}
ConstProxy(const ConstProxy& proxy)
: d_mutex(proxy.d_mutex)
, d_object(proxy.d_object)
{
proxy.d_mutex = NULL;
}
~ConstProxy()
{
if (d_mutex)
{
d_mutex->unlock();
}
}
const Object *operator->() const
{
return d_object;
}
};
Proxy operator->()
{
return Proxy(&d_mutex, &d_object);
}
ConstProxy operator->() const
{
return ConstProxy(&d_mutex, &d_object);
}
};
struct Foo
{
void foo()
{
std::cout << "Foo::foo" << std::endl;
}
};
int main()
{
ThreadSafeObject<Foo> myFoo;
myFoo->foo();
return 0;
}
Which uses the operator->() trick (when operator-> doesnt reutrn a pointer type, the compiler will keep calling operator-> on the returned values until eventually a regular pointer type is returned) and gives the following output:
Mutex::lock
Foo::foo
Mutex::unlock
Generally speaking though, an object that needs to be used by multiple threads shouldn't be exposing its internals like that, it would be safer to have it accept parameters and use its internal values to act on them.