How can one pass a non moveable object to a std::function? One easy enough alternative is passing a std::reference_wrapper which would create the need for the lifecycle of function be dependant on the object. Example code follows to explain the issue better.
class Player {
std::atomic_int runs {0};
std::string name;
public:
Player(std::string&& name) : name(std::move(name)) {} //...
void inc() { ++runs;}
};
class PlayerStats {
std::array<std::unique_ptr<Player>,2> players;
public:
PlayerStats() {
for(int i = 0; i<2 ; i++)
players[i] = std::unique_ptr<Player>(new Player{"player"+std::to_string(i)});
}
Player* const operator() (int index) const {
return players[index].get();
}
};
using player_total_f = std::function<Player* const(int index)>;
class GameStats {
std::string game;
std::string date;
player_total_f f;
public:
GameStats(std::string&& game, std::string&& date, player_total_f&& _f) :
game(std::move(game)), date(std::move(date)), f(std::move(_f)) {}
};
int main(int argc, char *argv[])
{
PlayerStats st;
//GameStats("game1","10.11",std::ref(st)); //this seems like the only possibility, no way to make GameStats own the functor
return 0;
}
How can I set the function here to PlayerStats, given that it is non copyable, a std::ref seems to be like the only possibility?
template<class F>
auto shared_function( F&& f ){
auto spf=std::make_shared<std::decay_f<F>>(std::forward<F>(f));
return [spf=std::move(spf)](auto&&...args)->decltype(auto){
return (*pf)(decltype(args)(args)...);
};
}
own it in a shared ptr. Changes semantics a bit, but fixes it.
Or write your own non-copying std function.
Related
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;
}
I need some help on a strange mix between function pointers and templates...
My target :
You have a class : template<typename B> class A, and A instanciate a B member. Now I want to acces B getter/setter.
I tried this :
class B_example
{
public:
B_example(int v):m_var(v){}
int getVar() { return m_var; }
void setVar(int v) { m_var = v; }
private:
int m_var;
};
template<typename B> class A
{
public:
A():m_b(B(5))
{
get = &m_b.getVar;
set = &m_b.setVar;
}
int (B::*get)();
void (B::*set)(int);
private:
B m_b;
};
int main(int argc, char** argv)
{
A<B_example> A_instance;
B_example B_instance(5);
int a = (A_instance.get*)();
std::cout << a << std::endl;
}
Thank's for any help.
Alexandre
First, fix the syntax errors:
get = &B::getVar;
set = &B::setVar;
Then, the member-function pointer needs to be called on an object. Without knowing the purpose of these strange pointers, I can't guess what you want to do here. Maybe you want to call on B_instance:
int a = (B_instance.*A_instance.get)();
Or maybe you want to call it on the m_b object within A_instance; but you can't do that because it's private. If that's the case, you probably just want regular member functions, rather than weird function pointers
int get() {return m_b.getVar();}
void set(int v) {m_b.setVar(v);}
These:
get = &m_b.getVar;
set = &m_b.setVar;
Should be:
get = &B::getVar;
set = &B::setVar;
And (A_instance.get*)() should be (B_instance.*A_instance.get)().
I think that any explanation without the code would be just more obscure. So here is the code where I tried to keep everything as simple as possible.
#include <vector>
#include <iostream>
class WithParametersBase
{
public:
WithParametersBase();
double getX() const {return 0.0;}
double getY() const {return 1.0;}
//let's say I want to access these members using an unified interface:
double getParameter(int index) const;
// For example index == 0 means getX and index == 1 means getY.
// I could implement it for example like this:
protected:
void addGetter(double (WithParametersBase::* getter)()const)
{
getters_.push_back(getter);
}
std::vector<double (WithParametersBase::*)()const> getters_;
};
WithParametersBase::WithParametersBase()
{
addGetter(&WithParametersBase::getX);
addGetter(&WithParametersBase::getY);
}
double WithParametersBase::getParameter(int index) const
{
return (this->*(getters_[index]))();
}
Indeed it works. With a test program:
int main(int argc, char *argv[])
{
WithParametersBase base;
std::cout << base.getParameter(0)
<< base.getParameter(1) << std::endl;
return 0;
}
The printout is correct:
01
But in case I wnat to extend this class:
class WithParametersDerived : public WithParametersBase
{
public:
WithParametersDerived();
double getZ() const {return 2.0;} // A new getter
};
WithParametersDerived::WithParametersDerived()
{
// I want to integrate the new getter into the previous interface
addGetter(&WithParametersDerived::getZ);
}
so that if I call:
WithParametersDerived derived;
std::cout << derived.getParameter(2) << std::endl;
I want to get get a
2
I cannot compile the program. I get an error:
error: no matching function for call to
'WithParametersDerived::addGetter
(double (WithParametersDerived::*)()const)'
Which is reasonable, but I do not know how else to implement it.
I want the creator of the derived class to be able to just add the new getter. I know, that it somehow doesn't feel right doing all this at runtime, but I do not see a template solution or a preprocessor solution. If you have some suggestions, please let me know. Anything!
I'll sidestep the why you need such a scheme, and focus on the how.
Instead of member function pointers, you can use a std::function<double ()>, which is a generic wrapper around any callable entity having the signature double foo(). To create a std::function<double ()> out of a member function and an object instance, you use std::bind as follows:
std::function<double ()> callback =
std::bind(&Class::memberFunction, objectInstancePointer);
If you're not using C++11, std::function and std::bind are also available in Boost as boost::function and boost::bind. The Boost documentation for these are mostly (if not entirely) applicable to their C++11 counterparts.
Instead of a std::vector, you can use a std::map to index getters by name. This may be more practical than maintaining a central list of parameter ID numbers.
If your parameters can be of different type than double, then you may want to consider using boost::any or boost::variant as the return type.
Here's a complete working example using std::function, std::bind, and std::map:
#include <cassert>
#include <map>
#include <iostream>
#include <functional>
class WithParametersBase
{
public:
WithParametersBase()
{
addGetter("X", std::bind(&WithParametersBase::getX, this));
addGetter("Y", std::bind(&WithParametersBase::getY, this));
}
virtual double getX() const {return 0.0;}
virtual double getY() const {return 1.0;}
// Access parameter by name
double getParameter(const std::string& name) const
{
auto getterIter = getters_.find(name);
assert(getterIter != getters_.end());
return getterIter->second();
}
protected:
typedef std::function<double ()> ParameterGetter;
typedef std::map<std::string, ParameterGetter> GetterMap;
void addGetter(const std::string& name, const ParameterGetter& getter)
{
getters_[name] = getter;
}
GetterMap getters_;
};
class WithParametersDerived : public WithParametersBase
{
public:
WithParametersDerived()
{
addGetter("Z", std::bind(&WithParametersDerived::getZ, this));
// Override base class getX
addGetter("X", std::bind(&WithParametersDerived::getX, this));
}
double getX() const {return 3.0;}
double getZ() const {return 2.0;} // A new getter
};
int main(int argc, char *argv[])
{
WithParametersBase base;
WithParametersDerived derived;
WithParametersBase& polymorphic = derived;
std::cout << base.getParameter("X")
<< base.getParameter("Y")
<< polymorphic.getParameter("X")
<< polymorphic.getParameter("Y")
<< polymorphic.getParameter("Z") << std::endl;
return 0;
}
The downside of this approach is that each instance of WithParametersBase (or a descendant) will contain a GetterMap. If you have a large amount of such objects, the memory overhead of all those GetterMaps may be undesirable.
Here's a more efficient solution that does away with std::function and std::bind. Regular function pointers and static member functions are used for getter callbacks. The object instance for which a parameter is requested is passed as an argument to these static member functions. In derived types, the instance reference is first downcast to the derived type before invoking the member function that does the actual getting.
There is now only one GetterMap per class instead of per object. Note the use of the "construct on first use" idiom in the getters() method to avoid static initialization order fiasco.
The downside with this solution is that there is more boilerplate code to write for each class derived from WithParametersBase. It might be possible to reduce the amount of boilerplate code using templates (it would definitely be possible with macros).
#include <cassert>
#include <map>
#include <iostream>
class WithParametersBase
{
public:
virtual double getX() const {return 0.0;}
virtual double getY() const {return 1.0;}
// Access parameter by name
double getParameter(const std::string& name) const
{
auto getterIter = getters().find(name);
assert(getterIter != getters().end());
return getterIter->second(*this);
}
protected:
typedef double (*ParameterGetter)(const WithParametersBase& instance);
typedef std::map<std::string, ParameterGetter> GetterMap;
static double xGetter(const WithParametersBase& instance)
{
return instance.getX();
}
static double yGetter(const WithParametersBase& instance)
{
return instance.getY();
}
static GetterMap makeGetterMap()
{
GetterMap map;
map["X"] = &WithParametersBase::xGetter;
map["Y"] = &WithParametersBase::yGetter;
return map;
}
virtual const GetterMap& getters() const
{
// Not thread-safe. Use std::call_once to make thread-safe.
static GetterMap map = makeGetterMap();
return map;
};
};
class WithParametersDerived : public WithParametersBase
{
public:
double getX() const {return 3.0;}
double getZ() const {return 2.0;} // A new getter
protected:
static double zGetter(const WithParametersBase& instance)
{
// It's reasonably safe to assume that 'instance' is of type
// WithParametersDerived, since WithParametersDerived was the one
// that associated "Z" with this callback function.
const WithParametersDerived& derived =
dynamic_cast<const WithParametersDerived&>(instance);
return derived.getZ();
}
static GetterMap makeGetterMap()
{
// We "inherit" the getter map from the base class before extending it.
GetterMap map = WithParametersBase::makeGetterMap();
map["Z"] = &WithParametersDerived::zGetter;
return map;
}
virtual const GetterMap& getters() const
{
// Not thread-safe. Use std::call_once to make thread-safe.
static GetterMap map = makeGetterMap();
return map;
};
};
int main(int argc, char *argv[])
{
WithParametersBase base;
WithParametersDerived derived;
WithParametersBase& polymorphic = derived;
std::cout << base.getParameter("X")
<< base.getParameter("Y")
<< polymorphic.getParameter("X")
<< polymorphic.getParameter("Y")
<< polymorphic.getParameter("Z") << std::endl;
return 0;
}
I have a class called Object which stores some data.
I would like to return it by reference using a function like this:
Object& return_Object();
Then, in my code, I would call it like this:
Object myObject = return_Object();
I have written code like this and it compiles. However, when I run the code, I consistently get a seg fault. What is the proper way to return a class object by reference?
You're probably returning an object that's on the stack. That is, return_Object() probably looks like this:
Object& return_Object()
{
Object object_to_return;
// ... do stuff ...
return object_to_return;
}
If this is what you're doing, you're out of luck - object_to_return has gone out of scope and been destructed at the end of return_Object, so myObject refers to a non-existent object. You either need to return by value, or return an Object declared in a wider scope or newed onto the heap.
You can only use
Object& return_Object();
if the object returned has a greater scope than the function. For example, you can use it if you have a class where it is encapsulated. If you create an object in your function, use pointers. If you want to modify an existing object, pass it as an argument.
class MyClass{
private:
Object myObj;
public:
Object& return_Object() {
return myObj;
}
Object* return_created_Object() {
return new Object();
}
bool modify_Object( Object& obj) {
// obj = myObj; return true; both possible
return obj.modifySomething() == true;
}
};
You can only return non-local objects by reference. The destructor may have invalidated some internal pointer, or whatever.
Don't be afraid of returning values -- it's fast!
I will show you some examples:
First example, do not return local scope object, for example:
const string &dontDoThis(const string &s)
{
string local = s;
return local;
}
You can't return local by reference, because local is destroyed at the end of the body of dontDoThis.
Second example, you can return by reference:
const string &shorterString(const string &s1, const string &s2)
{
return (s1.size() < s2.size()) ? s1 : s2;
}
Here, you can return by reference both s1 and s2 because they were defined before shorterString was called.
Third example:
char &get_val(string &str, string::size_type ix)
{
return str[ix];
}
usage code as below:
string s("123456");
cout << s << endl;
char &ch = get_val(s, 0);
ch = 'A';
cout << s << endl; // A23456
get_val can return elements of s by reference because s still exists after the call.
Fourth example
class Student
{
public:
string m_name;
int age;
string &getName();
};
string &Student::getName()
{
// you can return by reference
return m_name;
}
string& Test(Student &student)
{
// we can return `m_name` by reference here because `student` still exists after the call
return stu.m_name;
}
usage example:
Student student;
student.m_name = 'jack';
string name = student.getName();
// or
string name2 = Test(student);
Fifth example:
class String
{
private:
char *str_;
public:
String &operator=(const String &str);
};
String &String::operator=(const String &str)
{
if (this == &str)
{
return *this;
}
delete [] str_;
int length = strlen(str.str_);
str_ = new char[length + 1];
strcpy(str_, str.str_);
return *this;
}
You could then use the operator= above like this:
String a;
String b;
String c = b = a;
Well, it is maybe not a really beautiful solution in the code, but it is really beautiful in the interface of your function. And it is also very efficient. It is ideal if the second is more important for you (for example, you are developing a library).
The trick is this:
A line A a = b.make(); is internally converted to a constructor of A, i.e. as if you had written A a(b.make());.
Now b.make() should result a new class, with a callback function.
This whole thing can be fine handled only by classes, without any template.
Here is my minimal example. Check only the main(), as you can see it is simple. The internals aren't.
From the viewpoint of the speed: the size of a Factory::Mediator class is only 2 pointers, which is more that 1 but not more. And this is the only object in the whole thing which is transferred by value.
#include <stdio.h>
class Factory {
public:
class Mediator;
class Result {
public:
Result() {
printf ("Factory::Result::Result()\n");
};
Result(Mediator fm) {
printf ("Factory::Result::Result(Mediator)\n");
fm.call(this);
};
};
typedef void (*MakeMethod)(Factory* factory, Result* result);
class Mediator {
private:
Factory* factory;
MakeMethod makeMethod;
public:
Mediator(Factory* factory, MakeMethod makeMethod) {
printf ("Factory::Mediator::Mediator(Factory*, MakeMethod)\n");
this->factory = factory;
this->makeMethod = makeMethod;
};
void call(Result* result) {
printf ("Factory::Mediator::call(Result*)\n");
(*makeMethod)(factory, result);
};
};
};
class A;
class B : private Factory {
private:
int v;
public:
B(int v) {
printf ("B::B()\n");
this->v = v;
};
int getV() const {
printf ("B::getV()\n");
return v;
};
static void makeCb(Factory* f, Factory::Result* a);
Factory::Mediator make() {
printf ("Factory::Mediator B::make()\n");
return Factory::Mediator(static_cast<Factory*>(this), &B::makeCb);
};
};
class A : private Factory::Result {
friend class B;
private:
int v;
public:
A() {
printf ("A::A()\n");
v = 0;
};
A(Factory::Mediator fm) : Factory::Result(fm) {
printf ("A::A(Factory::Mediator)\n");
};
int getV() const {
printf ("A::getV()\n");
return v;
};
void setV(int v) {
printf ("A::setV(%i)\n", v);
this->v = v;
};
};
void B::makeCb(Factory* f, Factory::Result* r) {
printf ("B::makeCb(Factory*, Factory::Result*)\n");
B* b = static_cast<B*>(f);
A* a = static_cast<A*>(r);
a->setV(b->getV()+1);
};
int main(int argc, char **argv) {
B b(42);
A a = b.make();
printf ("a.v = %i\n", a.getV());
return 0;
}
It isn't really good practice to return an initiated object as it does go out of scope. There are rare instances that this is the desired option. It actually can be done if the class is a referencing counting smart pointer or some other smart pointer.
How does a reference-counting smart pointer's reference counting work?