Initialization of a member variable tuple - c++

I have the following code:
struct A
{
const string name;
A(string name) :name(name) {}
};
struct Parent
{
public:
const decltype(make_tuple(A("AA"))) children{ make_tuple(A("AA")) };
Parent()
{
}
};
Is it possible to avoid typing A("AA") twice?
Like when you use the auto keyword- but working.

You can move A("AA") or even better make_tuple(A("AA")) into its own function:
namespace {
auto make_children() { return make_tuple(A("AA")); }
}
struct Parent
{
public:
const decltype(make_children()) children{ make_children() };
Parent()
{
}
};
Live example
That way you only need to repeat the name of the helper function twice. Depending on the size/complexity of the expression in your real code, that might be a win.

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
}

Proper way to populate map of member objects and store one member with a smart pointer using RAII

So I am pretty new to C++ and am trying to understand smart pointers and the RAII design pattern. My question is this: say I have an object that contains a map of objects. I want one object at a time to be active, that is a want a pointer that points to one of the objects from the map. What is a proper RAII way to go about it using smart pointers? Below is what I have tried so far.
//StateMachine.h
std::unique_ptr<GameObject> p1Paddle = std::make_unique<GameObject>(Paddle());
std::unique_ptr<GameObject> p2Paddle = std::make_unique<GameObject>(Paddle());
std::unique_ptr<GameObject> ball = std::make_unique<GameObject>(Ball());
//StateMachine.cpp
StateMachine::StateMachine()
{
gameObjects["p1Paddle"] = std::pair <bool, std::unique_ptr<GameObject>>(false, std::move(p1Paddle));
gameObjects["p2Paddle"] = std::pair <bool, std::unique_ptr<GameObject>>(false, std::move(p2Paddle));
gameObjects["ball"] = std::pair <bool, std::unique_ptr<GameObject>>(false, std::move(ball));
}
void StateMachine::ChangeState(std::string key)
{
activeObject = std::move(gameObjects[key]);
}
Instead of using map and smart-pointer and based on your requirements that you only want a single object type at a given moment of time, perhaps you want a priority queue based implementation instead...
Here's a pseudo implementation:
#include <algorithm>
#include <cstdint>
#include <queue>
#include <string>
#include <vector>
enum class ComponentType {
PADDLE,
BALL
};
class Component {
protected:
ComponentType type_;
uint32_t id_;
priority_;
Component(ComponentType type, uint32_t id, float priority)
: type_{type}, id_{id}, priority_{prioity};
public:
virtual ~Component() {}
auto type() const { return type_; }
auto id() const { return id_; }
auto priority() const { return priority_; }
void updatePriority(float newPriority) { priority_ = newPriority; }
};
class Paddle : public Component {
private:
std::string name_;
public:
Paddle(std::string_view name, float priority) :
Component(ComponetType::PADDLE, std::stoi(name.data()), priority),
name_{name}
{}
auto name() const { return name_; }
};
class Ball : public Component {
private:
std::string name_;
public:
Ball(std::string_view name, float priority) :
Component(ComponentType::BALL, std::stoi(name.data()), priority),
name_{name}
{}
auto name() const { return name_; }
};
class CmpFunc {
public:
int operator(){ const Component& a, const Component& b) {
return a.priority() > b.priority();
}
};
class Game {
private:
//std::vector<Component*> components_;
std::priority_queue<Component*, std::vector<Component*>, CmpFunc> priority_;
public:
void initialize() {
Paddle paddle1("paddle_1", 0.1f);
Paddle paddle2("paddle_2", 0.2f);
Ball ball("ball", 0.3f");
addComponent(&paddle1);
addComponent(&paddle2);
addComponent(&ball);
}
void addComponent(Component* component) {
if (component == nullptr)
throw std::runtime_exception( "invalid component pointer!" );
//components_.push_back(component);
priority_.push(component);
}
auto getComponent() {
if (!priority_.empty()) {
auto component = priority_.top();
priority_.pop();
/*components_.erase(
std::remove(components_.begin(), components_.end(), component),
components_.end()
);*/
return component;
}
return nullptr;
}
};
This is just a pseudo example code to show a priority queue... I didn't show any implementation of updating or changing the priority queue of an object, nor did I show, how to directly use it based on some state X of the game or finite-state-machine... That would be an exercise for you...
I can not say whether this code will compile and run since I typed it out right here and have not yet tested it hence the pseudo code. You can play around with it and try to get it to compile and from there expand it to fit your own needs...

C++ array of object constructors

I have several classes named Child1, Child2 ... etc, inherited from object Parent. I need to create an object by its name, for example if I have string "Child1", I need to create object Child1 and so on.
I thought about something like:
struct registry_entry {
const char* name;
IREGISTRY* (*initializer)();
};
struct registry_entry registry_list[] =
{
{"xml", &REGISTRY_XML::REGISTRY_XML},
}
But I can't get address of object constructor.I believe that this problem must be already solved, and the solution is pretty simple, but I can't find it.
Constructors and destructors are special functions and cannot be accessed through function pointers.
You need to create a static member function like
struct REGISTRY_XML {
static IREGISTRY* create();
};
thus you can refer to it as
struct registry_entry registry_list[] =
{
{"xml", &REGISTRY_XML::create},
}
Your code looks very C-like and not very C++-like, but if you can actually use the full power of C++11, I would go with a combination of std::function, lambdas, std::unique_ptr and std::map.
Lambdas can wrap constructors without you having to write separate wrapper functions, std::function allows you to store the lambdas in a map, std::unique_ptr eliminates many memory-management bugs, and std::map performs the actual mapping from strings to initialiser functions.
Here is a complete example:
#include <functional>
#include <string>
#include <memory>
#include <map>
#include <iostream>
struct IREGISTRY {
virtual ~IREGISTRY() {}
virtual void print() = 0;
};
struct REGISTRY_XML : IREGISTRY { void print() override { std::cout << "XML\n"; } };
struct REGISTRY_INI : IREGISTRY { void print() override { std::cout << "INI\n"; } };
struct REGISTRY_JSON : IREGISTRY { void print() override { std::cout << "JSON\n"; } };
int main()
{
std::map<std::string, std::function<std::unique_ptr<IREGISTRY>()>> const registry_list = {
{ "xml", []() { return std::make_unique<REGISTRY_XML>(); } },
{ "ini", []() { return std::make_unique<REGISTRY_INI>(); } },
{ "json", []() { return std::make_unique<REGISTRY_JSON>(); } },
};
auto const initializer_iter = registry_list.find("xml");
if (initializer_iter != registry_list.end())
{
auto const initializer = initializer_iter->second;
auto const registry_ptr = initializer();
registry_ptr->print();
}
}

a function instead of copy-and-paste programming

I have an object, every member variable in this object has a name which I can acquire it by calling get_name() ,what I want to do is concatenate all the names of the member variables in alphabetical order, then do something. for example:
class CXMLWrapper<class T>
{
public:
CXMLWrapper(const char* p_name) : m_local_name(p_name)
{
}
//skip the get_name(), set_name() and others
private:
string m_local_name;
T m_type_var;
}
class object
{
public:
object() : m_team("team"), m_base("base")
{
}
public:
CXMLWrapper<string> m_team;
CXMLWrapper<string> m_base;
...
}
I have to hard-code like this:
object o;
string sign = o.m_base.get_name();
sign += o.m_team.get_name();
I need a function to do this instead of copying and pasting when the object varies. Anyone has an idea?
One way to do this in normal C++, provided all of the members belong to the same class or are derived from some base class will be to use variable number of arguments to a function. An example follows.
#include <stdarg.h>
string concatenateNames(int numMembers, ...)
{
string output;
va_list args;
va_start(args, numMembers);
for(int i = 0; i < numMembers; i++)
{
MemberClass *pMember = va_arg(args, MemberClass*);
output += pMember->get_name();
}
va_end(args);
return output;
}
class Object
{
public:
MemberClass x;
MemberClass y;
MemberClass z;
};
int main()
{
Object o;
string sign = concatenateNames(3, &o.x, &o.y, &o.z);
}
If the types of all the members are different, you can look into variadic templates of C++11x: http://en.wikipedia.org/wiki/Variadic_Templates, but I can't seem to find a way to do otherwise.
If variables which have name have a same type (or these types belongs one hierarchy) you can use map of these vars. Is not good way, but maybe it helps you
Example
class object
{
public:
object() //: m_team("team"), m_base("base")
{
this->vars["m_team"] = CXMLWrapper<string>("team");
//.....
}
public:
map<string, CXMLWrapper<string> > vars;
/*CXMLWrapper<string> m_team;
CXMLWrapper<string> m_base;*/
...
}
object o;
string sign;
for(auto& x : o.vars)//i cannot remember syntax of for of map
sign += x.get_name;
PS Sorry for my writing mistakes. English in not my native language.
One method is to have an external library of member names which the CXMLWrapper class updates:-
class BaseXMLWrapper
{
public:
void ListMembers (const char *parent)
{
// find "parent" in m_types
// if found, output members of vector
// else output "type not found"
}
protected:
void RegisterInstance (const char *parent, const char *member)
{
// find 'parent' in m_types
// if not found, create a new vector and add it to m_types
// find 'member' in parent vector
// if not found, add it
}
private:
static std::map <const std::string, std::vector <const std::string> >
m_types;
};
class CXMLWrapper <class T, const char *parent> : BaseXMLWrapper
{
public:
CXMLWrapper(const char* p_name) : m_local_name(p_name)
{
RegisterInstance (parent, p_name);
}
// you could override assignments, copy and move constructors to not call RegisterInstance
//skip the get_name() set_name()
private:
m_local_name;
}
class object
{
public:
object() : m_team("team"), m_base("base")
{
}
public:
CXMLWrapper<string, "object"> m_team;
CXMLWrapper<string, "object"> m_base;
...
};
This does add overhead to the construction of objects, but as it's only a constructor overhead it might not affect overall system performance much.
This looks like a "observe pattern", you just need to keep a single copy in object as a member variable "string name_;", and pass the name_s's reference into CXMLWrapper like this:
class CXMLWrapper<class T>
{
public:
CXMLWrapper(const string &name)
: local_name_(name)
{
}
//skip the get_name() set_name()
private:
const string &local_name_;
}
class object
{
public:
object()
: team_("team"),
base_("base"),
m_team(team_)
, m_base(base_)
{
}
public:
string team_;
string base_;
CXMLWrapper<string> m_team;
CXMLWrapper<string> m_base;
}

C++ Dynamic Dispatch without Virtual Functions

I've got some legacy code that, instead of virtual functions, uses a kind field to do dynamic dispatch. It looks something like this:
// Base struct shared by all subtypes
// Plain-old data; can't use virtual functions
struct POD
{
int kind;
int GetFoo();
int GetBar();
int GetBaz();
int GetXyzzy();
};
enum Kind { Kind_Derived1, Kind_Derived2, Kind_Derived3 /* , ... */ };
struct Derived1: POD
{
Derived1(): kind(Kind_Derived1) {}
int GetFoo();
int GetBar();
int GetBaz();
int GetXyzzy();
// ... plus other type-specific data and function members ...
};
struct Derived2: POD
{
Derived2(): kind(Kind_Derived2) {}
int GetFoo();
int GetBar();
int GetBaz();
int GetXyzzy();
// ... plus other type-specific data and function members ...
};
struct Derived3: POD
{
Derived3(): kind(Kind_Derived3) {}
int GetFoo();
int GetBar();
int GetBaz();
int GetXyzzy();
// ... plus other type-specific data and function members ...
};
// ... and so on for other derived classes ...
and then the POD class's function members are implemented like this:
int POD::GetFoo()
{
// Call kind-specific function
switch (kind)
{
case Kind_Derived1:
{
Derived1 *pDerived1 = static_cast<Derived1*>(this);
return pDerived1->GetFoo();
}
case Kind_Derived2:
{
Derived2 *pDerived2 = static_cast<Derived2*>(this);
return pDerived2->GetFoo();
}
case Kind_Derived3:
{
Derived3 *pDerived3 = static_cast<Derived3*>(this);
return pDerived3->GetFoo();
}
// ... and so on for other derived classes ...
default:
throw UnknownKindException(kind, "GetFoo");
}
}
POD::GetBar(), POD::GetBaz(), POD::GetXyzzy(), and other members are implemented similarly.
This example is simplified. The actual code has about a dozen different subtypes of POD, and a couple dozen methods. New subtypes of POD and new methods are added pretty frequently, and so every time we do that, we have to update all these switch statements.
The typical way to handle this would be to declare the function members virtual in the POD class, but we can't do that because the objects reside in shared memory. There is a lot of code that depends on these structs being plain-old-data, so even if I could figure out some way to have virtual functions in shared-memory objects, I wouldn't want to do that.
So, I'm looking for suggestions as to the best way to clean this up so that all the knowledge of how to call the subtype methods is centralized in one place, rather than scattered among a couple dozen switch statements in a couple dozen functions.
What occurs to me is that I can create some sort of adapter class that wraps a POD and uses templates to minimize the redundancy. But before I start down that path, I'd like to know how others have dealt with this.
You can use a jump table. This is what most virtual dispatches look like under the hood, and you CAN construct it manually.
template<typename T> int get_derived_foo(POD*ptr) {
return static_cast<T>(ptr)->GetFoo();
}
int (*)(POD*) funcs[] = {
get_derived_foo<Derived1>,
get_derived_foo<Derived2>,
get_derived_foo<Derived3>
};
int POD::GetFoo() {
return funcs[kind](this);
}
For a short example.
What exactly are the limitations of being in shared memory? I realized that I don't know enough here. Does it mean that I can't use pointers, because someone in another process will be trying to use those pointers?
You could use a string map, where each process gets it's own copy of the map. You'd have to pass this in to GetFoo() so that it can find it.
struct POD {
int GetFoo(std::map<int, std::function<int()>& ref) {
return ref[kind]();
}
};
Edit: Of course, you don't have to use a string here, you could use an int. I just used it as example. I should change it back. Infact, this solution is pretty flexible, but the important thing is, make a copy of process-specific data, e.g. function pointers or whatever, and then pass it in.
Here's the template-metaprogramming path I'm going down now. Here is what I like about it:
Adding support for a new kind only requires updating LAST_KIND and adding a new KindTraits.
There is a simple pattern for adding a new function.
Functions can be specialized for particular kinds if necessary.
I can expect compile-time errors and warnings, rather than mysterious run-time misbehavior, if I screw anything up.
There are a couple of concerns:
POD's implementation is now dependent upon the interfaces of all the derived classes. (This is already true in the existing implementation, so I'm not worried about it, but it is a bit of a smell.)
I'm counting on the compiler to be smart enough to generate code that is roughly equivalent to the switch-based code.
Many C++ programmers will scratch their heads upon seeing this.
Here's the code:
// Declare first and last kinds
const int FIRST_KIND = Kind_Derived1;
const int LAST_KIND = Kind_Derived3;
// Provide a compile-time mapping from a kind code to a subtype
template <int KIND>
struct KindTraits
{
typedef void Subtype;
};
template <> KindTraits<Kind_Derived1> { typedef Derived1 Subtype; };
template <> KindTraits<Kind_Derived2> { typedef Derived2 Subtype; };
template <> KindTraits<Kind_Derived3> { typedef Derived3 Subtype; };
// If kind matches, then do the appropriate typecast and return result;
// otherwise, try the next kind.
template <int KIND>
int GetFooForKind(POD *pod)
{
if (pod->kind == KIND)
return static_cast<KindTraits<KIND>::Subtype>(pod)->GetFoo();
else
return GetFooForKind<KIND + 1>(); // try the next kind
}
// Specialization for LAST_KIND+1
template <> int GetFooForKind<LAST_KIND + 1>(POD *pod)
{
// kind didn't match anything in FIRST_KIND..LAST_KIND
throw UnknownKindException(kind, "GetFoo");
}
// Now POD's function members can be implemented like this:
int POD::GetFoo()
{
return GetFooForKind<FIRST_KIND>(this);
}
You can experiment with Curiously recurring template pattern. It's a bit complicated, but when you cannot use pure virtual functions it can be helpful.
Here is an approach that uses virtual methods to implement the jump table, without requiring the Pod class or the derived classes to actually have virtual functions.
The objective is to simplify adding and removing methods across many classes.
To add a method, it needs to be added to Pod using a clear and common pattern, a pure virtual function needs to be added to PodInterface, and a forwarding function must be added to PodFuncs using a clear and common pattern.
Derived classes need only have a file static initialisation object to set things up, otherwise look pretty much like they already do.
// Pod header
#include <boost/shared_ptr.hpp>
enum Kind { Kind_Derived1, Kind_Derived2, Kind_Derived3 /* , ... */ };
struct Pod
{
int kind;
int GetFoo();
int GetBar();
int GetBaz();
};
struct PodInterface
{
virtual ~PodInterface();
virtual int GetFoo(Pod* p) const = 0;
virtual int GetBar(Pod* p) const = 0;
virtual int GetBaz(Pod* p) const = 0;
static void
do_init(
boost::shared_ptr<PodInterface const> const& p,
int kind);
};
template<class T> struct PodFuncs : public PodInterface
{
struct Init
{
Init(int kind)
{
boost::shared_ptr<PodInterface> t(new PodFuncs);
PodInterface::do_init(t, kind);
}
};
~PodFuncs() { }
int GetFoo(Pod* p) const { return static_cast<T*>(p)->GetFoo(); }
int GetBar(Pod* p) const { return static_cast<T*>(p)->GetBar(); }
int GetBaz(Pod* p) const { return static_cast<T*>(p)->GetBaz(); }
};
//
// Pod Implementation
//
#include <map>
typedef std::map<int, boost::shared_ptr<PodInterface const> > FuncMap;
static FuncMap& get_funcmap()
{
// Replace with other approach for static initialisation order as appropriate.
static FuncMap s_funcmap;
return s_funcmap;
}
//
// struct Pod methods
//
int Pod::GetFoo()
{
return get_funcmap()[kind]->GetFoo(this);
}
//
// struct PodInterface methods, in same file as s_funcs
//
PodInterface::~PodInterface()
{
}
void
PodInterface::do_init(
boost::shared_ptr<PodInterface const> const& p,
int kind)
{
// Could do checking for duplicates here.
get_funcmap()[kind] = p;
}
//
// Derived1
//
struct Derived1 : Pod
{
Derived1() { kind = Kind_Derived1; }
int GetFoo();
int GetBar();
int GetBaz();
// Whatever else.
};
//
// Derived1 implementation
//
static const PodFuncs<Derived1>::Init s_interface_init(Kind_Derived1);
int Derived1::GetFoo() { /* Implement */ }
int Derived1::GetBar() { /* Implement */ }
int Derived1::GetBaz() { /* Implement */ }
Here is an example using Curiously recurring template pattern. This may suit your needs if you know more info at the compile time.
template<class DerivedType>
struct POD
{
int GetFoo()
{
return static_cast<DerivedType*>(this)->GetFoo();
}
int GetBar()
{
return static_cast<DerivedType*>(this).GetBar();
}
int GetBaz()
{
return static_cast<DerivedType*>(this).GetBaz();
}
int GetXyzzy()
{
return static_cast<DerivedType*>(this).GetXyzzy();
}
};
struct Derived1 : public POD<Derived1>
{
int GetFoo()
{
return 1;
}
//define all implementations
};
struct Derived2 : public POD<Derived2>
{
//define all implementations
};
int main()
{
Derived1 d1;
cout << d1.GetFoo() << endl;
POD<Derived1> *p = new Derived1;
cout << p->GetFoo() << endl;
return 0;
}
Expanding on the solution you ended up with, the following solves the mapping to derived functions at program initialization:
#include <typeinfo>
#include <iostream>
#include <functional>
#include <vector>
enum Kind
{
Kind_First,
Kind_Derived1 = Kind_First,
Kind_Derived2,
Kind_Total
};
struct POD
{
size_t kind;
int GetFoo();
int GetBar();
};
struct VTable
{
std::function<int(POD*)> GetFoo;
std::function<int(POD*)> GetBar;
};
template<int KIND>
struct KindTraits
{
typedef POD KindType;
};
template<int KIND>
void InitRegistry(std::vector<VTable> &t)
{
typedef typename KindTraits<KIND>::KindType KindType;
size_t i = KIND;
t[i].GetFoo = [](POD *p) -> int {
return static_cast<KindType*>(p)->GetFoo();
};
t[i].GetBar = [](POD *p) -> int {
return static_cast<KindType*>(p)->GetBar();
};
InitRegistry<KIND+1>(t);
}
template<>
void InitRegistry<Kind_Total>(std::vector<VTable> &t)
{
}
struct Registry
{
std::vector<VTable> table;
Registry()
{
table.resize(Kind_Total);
InitRegistry<Kind_First>(table);
}
};
Registry reg;
int POD::GetFoo() { return reg.table[kind].GetFoo(this); }
int POD::GetBar() { return reg.table[kind].GetBar(this); }
struct Derived1 : POD
{
Derived1() { kind = Kind_Derived1; }
int GetFoo() { return 0; }
int GetBar() { return 1; }
};
template<> struct KindTraits<Kind_Derived1> { typedef Derived1 KindType; };
struct Derived2 : POD
{
Derived2() { kind = Kind_Derived2; }
int GetFoo() { return 2; }
int GetBar() { return 3; }
};
template<> struct KindTraits<Kind_Derived2> { typedef Derived2 KindType; };
int main()
{
Derived1 d1;
Derived2 d2;
POD *p;
p = static_cast<POD*>(&d1);
std::cout << p->GetFoo() << '\n';
p = static_cast<POD*>(&d2);
std::cout << p->GetBar() << '\n';
}