For this project, I cannot use C++11, or add any additional dependencies (e.g. Boost).
What I'm trying to achieve is this:
typedef void (*processorFunction)(int numItems, std::string* items);
class Files
{
public:
Files() : m_KVSeparator('='), m_ListSeparator(',') {}
~Files() {}
void ReadDataFile(std::string filename, std::map<std::string, processorFunction> processorFunctions);
char m_KVSeparator;
char m_ListSeparator;
};
void Files::ReadDataFile(std::string filename, std::map<std::string, processorFunction> processorFunctions)
{
// The file parsing and choosing of the function omitted for brevity:
processorFunction processor = ...;
int numItems = ...;
std::string* items = ...;
processor(numItems, items);
}
// Example parser:
void time_limit_parser(int& timeLimit, int numItems, std::string* items)
{
timeLimit = atoi(items[0].c_str());
}
int main()
{
// Omitted getting the global file manager pointer
Files* files = ...;
std::map<std::string, processorFunction> configProcessorFunctions;
int timeLimit;
// ****** WHAT GOES HERE? ******
files->ReadDataFile("config.dat", configProcessorFunctions);
}
My question is what do I put on the ****** WHAT GOES HERE? ****** line? I would use std::bind to partially apply it (a la time_limit_parser(timeLimit)), but I can't use C++11 for this project.
You wouldn't be able to do what you wanted even with bind because bind doesn't return function pointers. Instead, you'd have to use the std::function template to wrap them.
As it turns out, there's nothing preventing you from doing exactly that yourself.
struct BaseProcessor
{
virtual void operator()(int numItems, std::string* items) = 0;
};
struct TimeLimitParser : public BaseProcessor
{
int& timeLimit;
TimeLimitParser(int& limit)
: timeLimit(limit)
{}
virtual void operator()(int numItems, std::string* items)
{
time_limit_parser(timeLimit, numItems, items);
}
};
int main()
{
// Omitted getting the global file manager pointer
Files* files = ...;
std::map<std::string, processorFunction*> configProcessorFunctions;
int timeLimit;
TimeLimitParser parser(timeLimit);
configProcessorFunctions["foo"] = &parser;
files->ReadDataFile("config.dat", configProcessorFunctions);
}
Obviously you need to change the definition of processFunction to match a pointer/reference to BaseProcessor, and it's clearly not quite as pretty as using bind or lambdas, but if you can't upgrade or get boost that's about as good at it'll get without some serious wizardry.
Related
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
}
I have a class named Handler wich stores some lambdas. What I want to do is to have a std::vector of std::function that stores all my events, for exemple. I really can't figure out why lambdas doesn't work as I expected.
Here's the handler.h:
class Handler
{
public:
Handler();
~Handler();
void Register(const char* outcome, std::function<auto()> lambda);
void Trigger(const char* outcome);
private:
std::vector<int> identifier;
std::vector<char*> outcome;
std::vector<std::function<auto()>> func;
};
And handler.cpp:
Handler::Handler()
{
//ctor stuff here
}
Handler::~Handler()
{
this->func.clear();
this->outcome.clear();
this->identifier.clear();
//...
}
void Handler::Register(const char* outcome, std::function<auto()> lambda)
{
static int identifier = 0;
identifier++;
this->outcome.push_back((char*)outcome);
this->identifier.push_back(identifier);
this->func.push_back(lambda);
//Sort outcome
}
void Handler::Trigger(const char * outcome)
{
int i;
for (i = 0; i < this->identifier.size(); i++)
{
if (!strcmp(outcome, this->outcome.at(i)))
break;
}
this->func[i]();
}
However, if I specify lambdas in a Handler::Register it wont let me throwing no suitable user-defined conversion from "lambda []void ()->void" to "std::function<auto()> exists. In this example I use void return type but other types also error, I don't understant why can't the template from std::function deduce it out, if it is what's happening.
Handler* events = new Handler();
events->Register("Up", [=]() -> void { //Error here!
//do stuff
//return something?
});
Is there any other way to do this, like without overloading Handler::Register?
auto is not a type, so std::function<auto()> is not a type either. From how you are using it, std::function<void()> is probably what you want.
There are other problems with your code, as noted in the comments, so I would change Handler to this
class Handler
{
public:
Handler();
// default ~Handler is fine
void Register(std::string outcome, std::function<void()> lambda);
void Trigger(const std::string & outcome outcome) const;
void Trigger(std::size_t index) const;
private:
using Outcomes = std::map<std::string, std::function<void()>/*, custom string comparator ?*/>;
std::vector<Outcomes::iterator> identifier;
Outcomes outcomes;
};
void Handler::Register(std::string outcome, std::function<void()> func)
{
auto emplaced = outcomes.emplace(std::move(outcome), std::move(func));
identifier.push_back(emplaced.first);
}
void Handler::Trigger(const std::string & outcome) const
{
outcomes.at(outcome)();
}
void Handler::Trigger(std::size_t index) const
{
identifier[index]->second();
}
I want to write a class that can monitor a bunch of different values for easy debugging. Imagine setting "watches" in a visual debugger. I'm picturing something like this:
struct Foo {
int x = 0;
std::string s = "bar";
};
int main() {
Foo f;
ValueMonitor::watch("number", &f.x);
ValueMonitor::watch("string", &f.s);
for (int i = 0; i < 10; ++i) {
++f.x;
if (i > 5) {
f.s = "new string";
}
// print the current value of the variable with the given key
// these should change as the loop goes on
ValueMonitor::print("number");
ValueMonitor::print("string");
// or
ValueMonitor::printAll();
// obviously this would be unnecessary in this example since I
// have easy access to f, but imagine monitoring different
// values from all over a much larger code base
}
}
Then these could be easily monitored somewhere in the application's GUI or whatever.
However, I don't know how to handle the different types that would be stored in this class. Ideally, I should be able to store anything that has a string representation. I have a few ideas but none of them really seem right:
Store pointers to a superclass that defines a toString function or operator<<, like Java's Object. But this would require me to make wrappers for any primitives I want to monitor.
Something like boost::any or boost::spirit::hold_any. I think any needs to be type casted before I can print it... I guess I could try/catch casting to a bunch of different types, but that would be slow. hold_any requires defined stream operators, which would be perfect... but I can't get it to work with pointers.
Anyone have any ideas?
I found a solution somewhere else. I was pretty blown away, so might as well post it here for future reference. It looks something like this:
class Stringable
{
public:
virtual ~Stringable() {};
virtual std::string str() const = 0;
using Ptr = std::shared_ptr<Stringable>;
};
template <typename T>
class StringableRef : public Stringable
{
private:
T* _ptr;
public:
StringableRef(T& ref)
: _ptr(&ref) {}
virtual ~StringableRef() {}
virtual std::string str() const
{
std::ostringstream ss;
ss << *_ptr;
return ss.str();
}
};
class ValueMonitor
{
private:
static std::map<std::string, Stringable::Ptr> _values;
public:
ValueMonitor() {}
~ValueMonitor() {}
template <typename T>
static void watch(const std::string& label, T& ref)
{
_values[label] = std::make_shared<StringableRef<T>>(ref);
}
static void printAll()
{
for (const auto& valueItr : _values)
{
const String& name = valueItr.first;
const std::shared_ptr<Stringable>& value = valueItr.second;
std::cout << name << ": " << value->str() << std::endl;
}
}
static void clear()
{
_values.clear();
}
};
std::map<std::string, Stringable::Ptr> ValueMonitor::_values;
.
int main()
{
int i = 5;
std::string s = "test"
ValueMonitor::watch("number", i);
ValueMonitor::watch("string", s);
ValueMonitor::printAll();
i = 10;
s = "new string";
ValueMonitor::printAll();
return 0;
}
How would I return a(n existing) pointer to a known type from a string of its name? Say I created some map<string, double> called map1 and some vector<string> called vec1. I'd like to write a function that will return map1 from "map1" and vec1 from "vec1" (and an additional argument specifying the respective type of each).
Is this possible?
My ultimate goal is to get a QWidget by its name in QString form, since I'm working with a large number of them, though an answer should be framework-independent, right?
You need to perform some kind of dynamic dispatch. To do so you can simply start with exactly what you proposed:
enum class types { A = 0, B = 1 };
void (*handlers[])(void*) = { &HandleA, &HandleB };
::std::unordered_map<::std::string, ::std::tuple<types, void*>> registry;
Now all that remains is to perform the lookup:
void lookup(::std::string const& name)
{
auto& t = registry.at(name);
handlers[static_cast<size_t>(::std::get<0>(t))](::std::get<1>(t));
}
Automagic argument casting for handlers
The handlers all take an argument of type void* - this can be dealt with by adding a little template magic:
template<typename T, void(*f)(T*)>
void handle(void* arg)
{
f(static_cast<T*>(arg));
}
void (*handlers[])(void*) = { &handle<A, &HandleA>, &handle<B, &HandleB> };
Now, the prototype is e.g. void HandleA(A*).
Simple adding of objects to registry
With the current code, you can add objects to your registry like so:
A a;
registry.emplace("A #1", ::std::make_tuple(types::A, &a));
While this works perfectly, we would like to do something a bit more elegant. Let us start by changing the enum class types to something which also knows about the type we whish to represent it:
template<typename T> struct types;
template<> struct types<A> { static const size_t id = 0; };
template<> struct types<B> { static const size_t id = 1; };
Of course, now we need to fix the registry type:
::std::unordered_map<::std::string, ::std::tuple<size_t, void*>> registry;
And finally we can provide a simple insert function:
template<typename T>
void insert(::std::string const& name, T* object)
{
registry.emplace(name, ::std::make_tuple(types<T>::id, static_cast<void*>(object)));
}
Final usage example
A a;
insert("A #1", &a);
lookup("A #1");
The meta-object system already handles this, so the answer will be framework-specific because you generally need a code generator to get metadata about the C++ types that's not otherwise available.
QLineEdit * ed = ...;
ed->setObjectName("myObject");
... elsewhere in the code
foreach(QWidget * w, QCoreApplication::allWidgets()) {
// Lookup by name
if (w->objectName() == "myObject") {
...
}
// Lookup by type
if (qobject_cast<QLineEdit*>(w)) {
...
}
}
If you want to speed up the lookup, and the objects have unique names:
class Widgets {
typedef QMap<QString, QPointer<QWidget>> Data;
mutable Data m_map;
public:
Widgets() {
foreach(QWidget * w, QCoreApplication::allWidgets()) {
if (w->objectName().isEmpty()) continue;
m_map.insert(w->objectName(), w);
}
}
QWidget * lookupWidget(const QString & name) const {
Data::iterator it = m_map.find(name);
if (it == m_map.end()) return nullptr;
QWidget * w = it->data();
if (!w) m_map.erase(it); // The widget doesn't exist anymore
return w;
}
template <typename T> T * lookup(const QString & name) const {
return qobject_cast<T*>(lookupWidget(name));
}
void setName(QWidget * w, const QString & name) {
Q_ASSERT(! name.isEmpty());
w->setObjectName(name);
m_map.insert(name, w);
}
};
In your code, use widgets->setName() instead of setObjectName.
If you want to look-up by both name and type, where duplicate names are OK as long as they are all of different types:
class Widgets2 {
typedef QPair<QString, QString> Key;
typedef QMap<Key, QPointer<QWidget>> Data;
mutable Data m_map;
static Key keyFor(QWidget * w) {
return qMakePair(w->objectName(),
QString::fromLatin1(w->metaObject()->className()));
public:
Widgets2() {
foreach(QWidget * w, QCoreApplication::allWidgets()) {
if (w->objectName().isEmpty()) continue;
m_map.insert(keyFor(w), w);
}
}
QWidget * lookupWidget(const QString & name, const QString & type) const {
Data::iterator it = m_map.find(qMakePair(name, type));
if (it == m_map.end()) return nullptr;
QWidget * w = it->data();
if (!w) m_map.erase(it); // The widget doesn't exist anymore
return w;
}
template <typename T> T * lookup(const QString & name) const
{
return qobject_cast<T*>(lookupWidget(name,
QString::fromLatin1(T::staticMetaObject.className())));
}
void setName(QWidget * w, const QString & name) {
Q_ASSERT(! name.isEmpty());
w->setObjectName(name);
m_map.insert(keyFor(w), w);
}
};
The lookup works as follows:
widgets2->lookup<QLineEdit>("myObject")->setText("foo");
I'm leveraging the QObject and QPointer to make the widget registry safe to widget deletions - you won't ever get a dangling pointer back.
It is also possible to track object name changes, if you so wish: QObject emits the objectNameChanged signal.
All of this is of course a horrible hack around a broken design of your code. The fact that you need this means that you're very tightly coupling business logic and the GUI. You should use some kind of model-view architecture.
I want create object at run-time as in JavaScript:
person=new Object();
person.firstname="John";
I'm going to parse json and save to object. Methods will be known in advance and compiled.
I created this simple example and I would like to know if I'm going the right way.
adding and call method by string; function male and female will be added to object as methods to object.
Now in object is property gender, but later I want to do the same as with the functions. by methods setProperty and getProperty declared in Object. is it a good idea?
typedef struct method
{
(void)(*method_fn)(Object * _this, string params);
string method_name;
} method;
class Object{
private:
vector<method> methods;
public:
string gender;
Object(){};
~Object(){};
void addMethod(method metoda);
bool callMethod(string methodName,string params);
};
void male(Object *_this,string params) {
_this->gender="Male";
}
void female(Object* _this,string params) {
_this->gender="Female";
}
void Object::addMethod(method metoda)
{
methods.push_back(metoda);
}
bool Object::callMethod(string methodName,string params){
for(unsigned int i=0;i<methods.size();i++)
{
if(methods[i].method_name.compare(methodName)==0)
{
(*(methods[i].method_fn))(this,params);
return true;
}
}
return false;
}
using and it is work.
int _tmain(int argc, _TCHAR* argv[])
{
Object *object1 = new Object();
Object *object2 = new Object();
method new_method;
new_method.method_fn=♂
new_method.method_name="method1";
object2->addMethod(new_method);
new_method.method_fn=♀
new_method.method_name="method2";
object2->addMethod(new_method);
object1->callMethod("method1","");
object2->callMethod("method2","");
return 0;
}
You're better off using a map, and using references:
class Object {
public:
Object() {}
~Object() {}
typedef void (*Method)(Object& _this, const std::string& params);
void setMethod(const std::string& name, Method fn) { methods[name] = fn; }
bool callMethod(const std::string& name, const std::string& params);
private:
std::map<std::string, Method> methods;
std::map<std::string, std::string> properties;
};
bool Object::callMethod(const std::string& name, const std::string& params)
{
// Look for it.
// Note: in C++11, you can do this instead:
// auto methodIter = methods.find(name);
std::map<std::string, Method>::iterator methodIter = methods.find(name);
if(methodIter == methods.end())
return false;
// Found it.
(*(methodIter->second))(*this, params);
return true;
}
Note that I added properties which does the same thing as methods except it maps names to strings instead of functions. This replaces your string gender; stuff.
Anyway, just some small changes to your main function, to remove the need for a method structure:
int _tmain(int argc, _TCHAR* argv[])
{
Object *object1 = new Object();
Object *object2 = new Object();
object1->addMethod("method1", &male);
object2->addMethod("method2", &female);
object1->callMethod("method1", "");
object2->callMethod("method2", "");
return 0;
}
P.S. I used the std:: prefixed versiojns of the standard type names because you should never have using namespace std; or similar in a header file.
It's mostly OK. You've created dynamic containers for your methods and their associated names. This is A LITTLE like what a dynamic language would do, behind the scenes.
What you can do to improve it is use hash maps, for more speed. For example:
typedef void (*Method)(Object& _this, const string& params);
typedef std::unordered_map<string, Method> NameToMethodMap;
typedef std::unordered_map<string, string> NameToValueMap;
class Object {
private:
NameToMethodMap methods;
public:
NameToValueMap attributes;
void addMethod(const std::string& name, Method& method) {
// TODO: check that name isn't in there first
methods[name] = method;
}
};
int main() {
Object o;
o.attributes["gender"] = "male";
}