How to automatically add handler to the global map? - c++

I have Application singleton wich has method
void addHandler(const std::string& command, std::function<std::string (const std::string&)> handler)
I want to create a lot of cpp files with handlers like this
//create_user_handler.cpp
Application::getInstance()->addHandler("create_user", [](std::string name) {
UserPtr user = User::create(name);
return user->toJson();
});
How automatically call this from my cpp files?
I try to change from void addHandler to bool addHandler and than use
namespace {
bool b = Application::getInatance()->addHandler......
}
but it didn't work for me
Udate
It works now, but could it be done in a better way, without unused bool variable?

Make use of static class instantiation.
Pseudo code -
Add a registrator class.
class Registrator {
template <typename Func>
Registrator(const std::string& name, Func handler) {
Application::getInstance()->addHandler(name, handler);
}
};
And in each cpp file, create a static class object:
test.cpp
static Registrator test_cpp_reg("create_user", [](std::string name) {
UserPtr user = User::create(name);
return user->toJson();
});

I assume that addHandler() should return bool? Otherwise, you can't assign to the bool variable.
To remove the bool return of addHandler, make the call from the constructor of some other class that you in turn instantiate statically.
This kind of code can work, but it is tricky. The problem is that in C/C++, the order of static-storage initializers is undefined. So while a static initializer is allowed to call any code, if that code references as-yet-uninitialized data, it will fail. And unfortunately the failure is non-deterministic. It might work for a while, and then you change some compiler flag or module order, and splat!
One trick is to implement the instance state of getInstance() using a dumb pointer, because that is always initialized to zero (null) before any of the static initializers fire. For example, the following code will print "Added foo" before main starts:
#include <string>
#include <functional>
#include <map>
#include <iostream>
class Application {
public:
static Application* getInstance() {
// Not thread-safe!
if (instance == 0) {
instance = new Application;
}
return instance;
}
typedef std::function<std::string(const std::string&)> HANDLER;
typedef std::map<std::string, HANDLER> HANDLER_MAP;
bool addHandler(const std::string& command, HANDLER handler) {
handlerMap.insert(HANDLER_MAP::value_type(command, handler));
std::cout << "Added " << command << "\n";
return true;
}
HANDLER_MAP handlerMap;
static Application* instance;
};
Application* Application::instance;
std::string myHandler(const std::string&) { return ""; }
bool b = Application::getInstance()->addHandler("foo", myHandler);
int main()
{
return 0;
}

Related

Is there a way to have lambda function added to a map at compile time or before main even though it's within local scope in c++?

#define callback(id, func) std::pair<decltype(id), decltype(func)>(id, func)
The question sounds tricky. What I want to do is to build a id-function mapping dispatcher without user doing it at global scope. When the user writes objectA.send(b, callback(id, []{})) like this inside any function, the lambda expression is somehow registered into a global map at compile time or before main function so that I can lookup it through the id later. I want to build a library that construct the lookup map without user pay any attention to the map. The reason why I think it can be done at compile time is that if the id and the lambda funcion are given staticly before run time, a lookup map with constant value can be deduced at compile time theoretically
You can set up a Factory to be a singleton that creates the lambdas, and records them in a std::map as well.
A different file, Constructible.h, will contain functions that set up that map, and perform searches into it.
A .cpp file, Registration.cpp, will contain calls to the function (in Constructible.h) which sets up the map with the allowed lambdas you want.
You can update the list of allowed lambdas when needed.
The file will have to compile along main.cpp. If they are in the same folder this is easy and automatic on most IDEs.
The .cpp file is wrapped in an anonymous namespace in order to shield it from users tampering with it.
In short:
Registration.cpp #includes Constructible.h.
Registration.cpp sets global variables of type Helper(defined in Constructible.h).
Construction of the first Helper object instantiates the Factory.
All Helpers are registered with the Factory.
main.cpp program can then execute its tasks smoothly.
main.cpp:
#include <Constructible.h>
#include <Factory.h>
#include <string>
#include <iostream>
#include <Lambda.h>
int main()
{
std::string name = "this_lambda";
double a_number = 57.1;
Lambda* ptr_to_func = Factory::Instance().CreateLambda(name, a_number);
//...
return 0;
}
Lambda.h:
#include <functional>
// here you define your lambdas, for instance:
using Lambda = std::function<double (double)>;
using AnotherLambda = std::function<double (int)>;
Lambda my_lambda =
[](double x){
return x + 1.23;
};
AnotherLambda my_lambda_2 =
[](int x){
return x / 2;
};
Factory.h:
#include <iostream>
#include <map>
#include <string>
#include <Lambda.h>
class Factory
{
public:
typedef Lambda* (*CreateLambdaFunction)(double);
// insert the parameters of your lambda as arguments above,
// here we have double
static Factory& Instance();
void Register(std::string, CreateLambdaFunction);
Lambda* CreateLambda(std::string a_id, double input);
~Factory(){};
private:
std::map<std::string, CreateLambdaFunction> MyCreatorFunctions;
Factory(){}
Factory(const Factory&) = default;
Factory& operator=(const Factory&) = default;
Factory(Factory&&) = default;
Factory& operator=(Factory&&) = default;
};
void Factory::Register(string a_id, CreateLambdaFunction CreatorFunction)
{
MyCreatorFunctions.insert(pair<string,CreateLambdaFunction>(a_id, CreatorFunction));
}
Lambda* Factory::CreateLambda(string a_id, double input)
{
map<string, CreateLambdaFunction>::const_iterator
i = MyCreatorFunctions.find(a_id);
if (i == MyCreatorFunctions.end())
{
std::cout << a_id << " is an unknown object\n";
return NULL;
}
return (i->second)(input);
}
Factory& Factory::Instance()
{
static Factory myFactory;
return myFactory;
}
Constructible.h:
#include <iostream>
#include <Lambda.h>
#include <Factory.h>
#include <string>
template <class T> // T a type in the Lambda class hierarchy
class Helper
{
public:
Helper(std::string);
static Lambda* Create(double);
};
template <class T>
Lambda* Helper<T>::Create(double input)
{
return new T(input);
}
template <class T>
Helper<T>::Helper(std::string id)
{
Factory& MyFactory = Factory::Instance();
MyFactory.Register(id, Helper<T>::Create);
}
Registration.cpp:
#include <Constructible.h>
namespace
{
Helper<Lambda> RegisterLambda("this_lambda");
// another lambda
Helper<AnotherLambda> RegisterAnotherLambda("another_lambda");
}

C++ lazy singleton hangs on loading

I have lazy singleton class, that needs to be serialized using boost on the first call.
Header file:
class Singleton
{
public:
static Singleton& Instance()
{
static Singleton theSingleInstance;
return theSingleInstance;
}
void load();
private:
Singleton();
Singleton(const Singleton& root);
Singleton& operator=(const Singleton&);
std::map<std::string,std::string > m_desc;
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive& arc, const unsigned int version)
{
arc & BOOST_SERIALIZATION_NVP(m_desc);
}
const char* FILENAME = "./config.xml";
};
Source file
#include "singleton.h"
Singleton::Singleton()
{
load();
}
void Singleton::load()
{
try
{
std::ifstream f(FILENAME);
boost::archive::xml_iarchive arc(f);
arc & boost::serialization::make_nvp("Config",Instance());
}
catch(...)
{
std::cout << "Exception" << std::endl;
}
}
So when I try to start my code using this singleton, it hangs. With the debugger I can see that it does not go to load() method many times (and it's ok). When I pause the debugger, it stops on the line return theSingleInstance;, but it does not go through the breakpoint on this line many times also. What am I doing wrong?
You call load from inside the constructor. Which means that you're in the constructor of your static theSingleInstance when you... call Instance
:
#0 in Singleton::load at test.cpp <test.cpp>
#1 in Singleton::Singleton at test.cpp <test.cpp>
#2 in Singleton::Instance at test.cpp <test.cpp>
#3 in main at test.cpp <test.cpp>
Since construction c++11 function-local statics is guaranteed to be thread safe, which means - in your implementation - that execution will block until the instance is fully constructed (or construction failed, so it can be retried).
Of course, that will never happen because construction is waiting for itself.
0x00000000004030f5 <+629>: callq 0x402be0 <__cxa_guard_acquire#plt>
=> 0x00000000004030fa <+634>: test %eax,%eax
0x00000000004030fc <+636>: je 0x402ff1 <Singleton::load()+369>
Of course this is fixed by not using the external accessor while still constructing the instance, as you already found out.
You might want to consider the practice of giving singletons value-semantics - in case one day you don't want it to be a singleton any more and you want to avoid refactoring.
The other advantage is that it provides full encapsulation:
for example:
// config.h - extremely sparse interface
#include <string>
struct config
{
/// Return a named value from the program's configuration
/// #param name is the name of the required parameter
/// #post the config file shall be cached
/// #return the value if it exists
/// #except std::invalid_argument if the value does not exist
/// #except other exceptions if the config file does not load
///
const std::string& value(const std::string& name) const;
private:
struct impl;
static impl& get();
};
// config.cpp - the implementation
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/map.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <fstream>
#include <map>
struct config::impl
{
impl()
{
std::ifstream f(FILENAME);
boost::archive::xml_iarchive arc(f);
arc & boost::serialization::make_nvp("Config", *this);
}
std::map<std::string,std::string > m_desc;
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive& arc, const unsigned int version)
{
arc & BOOST_SERIALIZATION_NVP(m_desc);
}
static constexpr const char* FILENAME = "./config.xml";
};
config::impl& config::get() {
static impl _;
return _;
}
const std::string& config::value(const std::string& name) const
{
return get().m_desc.at(name);
}
// demo.cpp
// note - config is copyable, and this has almost no cost
void do_something_with(config cfg)
{
}
struct no_config {}; // some other config source?
// now I can switch on config type at compile time - code can be
// more generic
void do_something_with(no_config)
{
}
int main()
{
// single-use
std::string my_value = config().value("foo");
// pass my config source to a function
do_something_with(config());
// a similar function that uses a different config source
do_something_with(no_config());
return 0;
}
The answer was simple: to replace this line
arc & boost::serialization::make_nvp("Config",Instance());
with
arc & boost::serialization::make_nvp("Config",*this);

Call member function when class type is not known

I want to have a class that can have a callback set to a pointer to member function. This means I need to store the address of the function, and the address of the object instance. The function should have the proper prototype and return value to what the callback expects.
I've played around with std::mem_fn and boost::bind (with the Boost Signals2 library), but it seems like I have to know the type of the class containing the callback function to store this information.
It seems like there should be a way to store a couple void* that would point to any object/function, but this obviously smells funny, loses type safety, etc.
Given a class SomeClass with a method some_method, I want to be able to do something like this:
SomeClass obj;
some_other_class.set_callback(&SomeClass::some_method, &obj);
Here is how I was able to accomplish this using Boost. Note that this uses Boost signals, and seems like overkill for a simple callback. Also, there is the issue of signals using "combiners" to determine the return value of the callback, since there are potentially multiple slots connected to a single signal. I only need support for a single callback. Also note that this is a complete compilable program:
#define _SCL_SECURE_NO_WARNINGS
#include <iostream>
#include <boost/bind.hpp>
#include <boost/signals2.hpp>
#include <string>
using namespace std;
struct MessageSource
{
boost::signals2::signal<void(const string &)> send_message;
typedef boost::signals2::signal<void(const string &)>::slot_type slot_type;
template<typename A, typename B>
boost::signals2::connection connect(A a, B b)
{
return send_message.connect(boost::bind(a, b, _1));
}
void send_msg(const string& msg)
{
send_message(msg);
}
};
struct Printer
{
void print(const string& msg) { std::cout << msg << std::endl; };
};
int main()
{
{
Printer p;
MessageSource s;
s.connect(&Printer::print, &p);
s.send_msg("test");
}
system("pause");
return 0;
}
I think the magic here is the fact that boost::bind() is able to handle a variety of types for its first argument. I just don't get how it can hold onto it in a private field of some sort without knowing the type...
Is this a case where a functor is really the right solution? It seems like member functions are so much more convenient to use...
Based on the comment by cdhowie above, I was able to come up with the following solution using std::function and std::bind:
#include <iostream>
#include <string>
#include <functional>
using namespace std;
struct MessageSource
{
function<void(const string& msg)> _callback;
template<typename A, typename B>
void connect(A func_ptr, B obj_ptr)
{
_callback = bind(func_ptr, obj_ptr, placeholders::_1);
}
void send_msg(const string& msg)
{
if (_callback)
_callback(msg);
}
void disconnect()
{
_callback = nullptr;
}
};
struct Printer
{
void print(const string& msg) { std::cout << msg << std::endl; };
};
int main()
{
{
Printer p;
MessageSource s;
s.connect(&Printer::print, &p);
s.send_msg("test");
s.disconnect();
s.send_msg("test again");
}
system("pause");
return 0;
}

How to initialize stl map when they are defined as static variable as a class memebers

I am getting linker error, for the following code. I want to know how do I initialize stl map
#include <iostream>
#include <map>
#include <string>
class Test {
public:
Test() {
}
static void setSerializer(void* fnptr, std::string className) {
m_registry.insert(std::make_pair(className, fnptr));
}
static void* getSerializer(std::string className) {
return m_registry.find(className)->second;
}
private:
static std::map<std::string, void*> m_registry;
};
void fn() {
}
int main() {
Test::setSerializer(&fn,"abc");
return 0;
}
You need to define your static variable in class implementation - as you do for extern C++ variables. Just declaring it in class isn't sufficient!
To do this put the code below to the .cpp file:
std::map<std::string, void*> Test::m_registry;
You need to initialize your static member in .cpp file. Normally we declare class in .h file and put definition into .cpp file. I did a bit enhancement to your code as shown below:
Test.h
class Test
{
public:
Test() { }
static void setSerializer(std::string className, void* fnptr); // I swap the order of parameter. it makes more sense to have name and pointer pair
static void* getSerializer(std::string className);
private:
static std::map<std::string, void*> m_registry;
};
Test.cpp
std::map<std::string, void*> Test::m_registry; // initialize static member here
void Test::setSerializer(std::string className, void* fnptr)
{
m_registry.insert(std::make_pair(className, fnptr));
}
void* Test::getSerializer(std::string className) {
auto iter = m_registry.find(className); // check if iterator is valid
if (iter != m_registry.end() )
{
return (*iter).second;
}
return NULL;
}

Function calls with class members?

Before I present the code which is found at the bottom of this post I would like to talk about the issue and the fix's that I do not desire. Okay basically I've created a GUI from scratch sort of and one requirement I wanted for this was allow components to have their own click executions so if i click a button or tab etc.. It would call Component->Execute(); Well normally you would do something like a switch statement of ids and if that components ID equaled n number then it would perform this action. Well that seemed kinda dumb to me and I thought there has to be a better way. I eventually tried to incorporate a feature in JAVA where you would do like Component.AddActionListener(new ActionListener( public void execute(ActionEvent ae) { })); or something like that and I thought that this feature has to be possible in C++. I eventually came across storing void functions into a variable in which could be executed at any time and modified at any time. However I hadn't noticed an issue and that was this only worked with static functions. So below you'll see my problem. I've patched the problem by using a pointer to SomeClass however this would mean having an individual function call for every class type is there no way to store a function callback to a non-static class member without doing the below strategy? and instead doing a strategy like the commented out code?
//Main.cpp
#include <iostream> //system requires this.
#include "SomeClass.h"
void DoSomething1(void)
{
std::cout << "We Called Static DoSomething1\n";
}
void DoSomething2(void)
{
std::cout << "We Called Static DoSomething2\n";
}
int main()
{
void (*function_call2)(SomeClass*);
void (*function_call)() = DoSomething1; //This works No Problems!
function_call(); //Will Call the DoSomething1(void);
function_call = DoSomething2; //This works No Problems!
function_call(); //Will Call the DoSomething2(void);
SomeClass *some = new SomeClass(); //Create a SomeClass pointer;
function_call = SomeClass::DoSomething3; //Static SomeClass::DoSomething3();
function_call(); //Will Call the SomeClass::DoSomething3(void);
//function_call = some->DoSomething4; //Non-Static SomeClass::DoSomething4 gives an error.
//function_call(); //Not used because of error above.
function_call2 = SomeClass::DoSomething5; //Store the SomeClass::DoSomething(SomeClass* some);
function_call2(some); //Call out SomeClass::DoSomething5 which calls on SomeClass::DoSomething4's non static member.
system("pause");
return 0;
}
//SomeClass.hpp
#pragma once
#include <iostream>
class SomeClass
{
public:
SomeClass();
~SomeClass();
public:
static void DoSomething3(void);
void DoSomething4(void);
static void DoSomething5(SomeClass* some);
};
//SomeClass.cpp
#include "SomeClass.h"
SomeClass::SomeClass(void)
{
}
SomeClass::~SomeClass(void)
{
}
void SomeClass::DoSomething3(void)
{
std::cout << "We Called Static DoSomething3\n";
}
void SomeClass::DoSomething4(void)
{
std::cout << "We Called Non-Static DoSomething4\n";
}
void SomeClass::DoSomething5(SomeClass *some)
{
some->DoSomething4();
}
Secondary Fix for what I'll do not an exact answer I wanted but it meets my needs for now along with allowing additional features which would have become overly complicate had this not existed.
//Component.hpp
#pragma once
#include <iostream>
#include <windows.h>
#include <d3dx9.h>
#include <d3d9.h>
#include "Constants.hpp"
#include "ScreenState.hpp"
#include "ComponentType.hpp"
using namespace std;
class Component
{
static void EMPTY(void) { }
static void EMPTY(int i) { }
public:
Component(void)
{
callback = EMPTY;
callback2 = EMPTY;
callback_id = -1;
}
Component* SetFunction(void (*callback)())
{
this->callback = callback;
return this;
}
Component* SetFunction(void (*callback2)(int), int id)
{
this->callback_id = id;
this->callback2 = callback2;
return this;
}
void execute(void)
{
callback();
callback2(callback_id);
}
}
The syntax for pointers-to-member-functions is as follows:
struct Foo
{
void bar(int, int);
void zip(int, int);
};
Foo x;
void (Foo::*p)(int, int) = &Foo::bar; // pointer
(x.*p)(1, 2); // invocation
p = &Foo::zip;
(x.*p)(3, 4); // invocation
Mind the additional parentheses in the function invocation, which is needed to get the correct operator precedence. The member-dereference operator is .* (and there's also ->* from an instance pointer).