Vector with objects that have function pointers of varying type











up vote
1
down vote

favorite












I'm trying to implement a vector that represents a list of TimedCallback objects who inherits from a base class.
They hold some basic variables, plus a function pointer which is the main feature.
The function should be able to return any type and have any params.
I pass them as lambdas into the functions, not really any problems so far.



This is the relevant code:



std::vector<std::unique_ptr<TimedCallbackBase>> m_TimerCallbackList;

struct TimedCallbackBase {
TimedCallbackBase() = default;
virtual ~TimedCallbackBase() = default;

template<typename T> T run()
{
return dynamic_cast< TimedCallback<T> & >(*this).Run();
}
template<typename T> std::string name()
{
return dynamic_cast< TimedCallback<T> & >(*this).Name;
}
template<typename T> TaskTimer time()
{
return dynamic_cast< TimedCallback<T> & >(*this).Time;
}
template<typename T> int repeatcount()
{
return dynamic_cast< TimedCallback<T> & >(*this).RepeatCount;
}
};

template <typename Fu>
struct TimedCallback : TimedCallbackBase {
TimedCallback(const std::string& name, const std::string& time, Fu f, int r) : Name(name), Run(f), Time(time), RepeatCount(r) {}
std::string Name;
Fu Run;
TaskTimer Time;
int RepeatCount;
};

template<typename Fu>
void Schedule(const std::string& name, const std::string& time, Fu f, int repeatCount = 0) {
TimedCallback cb(name, time, f, repeatCount);
if (!vec_contains(m_TimerCallbackList, cb)) {
m_TimerCallbackList.push_back(cb);
}
else { Global->Log->Warning(title(), "Callback '"+name+"' already exists."); }
}


My problem is this method. I am unable to properly run the func pointers.



void _RunTimers() {
if (m_TimerCallbackList.size() > 0) {
for (auto &t : m_TimerCallbackList) {
if (t != nullptr) {

std::string _name = t.get()->name(); // wrong syntax, or signature?
TaskTimer _time = t.get()->time();
int _repeatcount = t.get()->repeatcount();
//auto _run = t.get()->run(); ??

Global->t("Callback name: " + _name);
Global->t("Callback time: " + _time.GetRealTimeAsString());
Global->t("Callback count: " + its(_repeatcount));
}
}
}
else { Global->Log->Warning(title(), "No timed tasks to run at this time."); }
}


I intend to use the code like this:



Task->Schedule("testTimer", "10sec", [&]{ return Task->Test("I'm a 10sec timer."); });

_RunTimers();


I feel like I am pretty far from doing this correctly.
I don't want to specify any templates for the _RunTimers(); method.
Please help me understand how this can possible.



Edit:



I mean, I guess it is totally possible to just define a bunch of typedefs along the lines of



using int_func = std::function<int()>;


for every possible case and then overload my wrapper object, but I was looking for something more dynamic and change-proof.



Edit 2: After implementing the suggested changes



Note: I've renamed the methods for ambiguity's sake.
(The method Test() is not included here, but simply does a std::cout of a string param)



main:



Callback myCallback = make_callback(&TaskAssigner::Test, "I'm a 5sec timer.");

Task->ScheduleJob("timer1", "5sec", myCallback, -1);
Task->RunScheduledJobs();


Utilities:



typedef double RetVal;
typedef std::function<RetVal()> Callback;

template <class F, class... Args>
Callback make_callback(F&& f, Args&&... args)
{
auto callable = std::bind(f, args...); // Here we handle the parameters
return [callable]() -> RetVal{ return callable(); }; // Here we handle the return type
}

struct TimedCallback {
TimedCallback(cstR name, cstR time, Callback f, int r)
: Name(name), Run(f), Time(time), RepeatCount(r) {}

RetVal operator()() const { return Run(); }

bool operator==(const TimedCallback& other) {
if (Name == other.Name && RepeatCount == other.RepeatCount) { return true; }
return false;
}

const bool operator==(const TimedCallback& other) const {
if (Name == other.Name && RepeatCount == other.RepeatCount) { return true; }
return false;
}

std::string Name;
Callback Run;
TaskTimer Time;
int RepeatCount;
};


TaskAssigner .h:



void ScheduleJob(const std::string& name, const std::string& time, const Callback& func, int repeatCount = 0);

void RunScheduledJobs();

std::vector<TimedCallback> m_TimerCallbackList;


TaskAssigner.cpp:



void TaskAssigner::ScheduleJob(const std::string& name, const std::string& time, const Callback& func, int repeatCount) {

TimedCallback cb(name, time, func, repeatCount);

if (!vec_contains(m_TimerCallbackList, cb)) {
m_TimerCallbackList.emplace_back(cb);
}
else { Global->Log->Warning(title(), "Callback '" + name + "' already added."); }
}

void TaskAssigner::RunScheduledJobs() {
if (m_TimerCallbackList.size() > 0) {
for (auto &t : m_TimerCallbackList)
{
RetVal value = t();
//Global->t("Callback result: " + std::to_string(value));
Global->t("Callback name: " + t.Name);
Global->t("Callback time: " + t.Time.GetRealTimeAsString());
Global->t("Callback count: " + its(t.RepeatCount));
}
}
else { Global->Log->Warning(title(), "No timed tasks to run at this time."); }
}


Current problem:



Compiler says: C3848: expression having type 'const std::_Bind, const char(&)[18]>' would lose some const-volatile qualifiers in order to call .....



I tried researching and some have mentioned a bug with VS 2013 regarding bind and auto. Solutions include typing the signature rather than auto-ing it, or remove/add proper const(?). Not sure if this is the same bug or if my implementation is still incorrect.
(Bug: https://stackoverflow.com/a/30344737/8263197)



I am unsure how exactly I can make RetVal support any value with this typedef.
I tried



    template<typename T>
struct CallbackReturnValue {
CallbackReturnValue(T v) : value(v) {}
T value;
};


but then I will still need to template the other supporting methods. What am I mistaking here?










share|improve this question
























  • You never stated what the issue is. Is this a compiling issue? A runtime issue? A design issue?
    – PaulMcKenzie
    Nov 10 at 17:54










  • t.get()->name(); Doesn't work because compiler cannot deduce the template parameter for the function template template<typename T> std::string TimedCallbackBase::name(); . But I really don't see the point of the base class if every function just casts to the derive class. Did you do it to get rid of the template parameter in order to be able to store in the vector?
    – Quimby
    Nov 10 at 18:01










  • As written runtimers doesn't need the return value.
    – Yakk - Adam Nevraumont
    Nov 10 at 18:43










  • @PaulMcKenzie Pardon me. It's a compiling issue. I'm having problems understanding what the legal syntax is for what I want to achieve.
    – Mads Midtlyng
    Nov 11 at 6:23










  • @Quimby Exactly, I was trying to get rid of the template parameter so that the function which runs the list of callback-able objects doesn't have to be defined like that.
    – Mads Midtlyng
    Nov 12 at 4:50















up vote
1
down vote

favorite












I'm trying to implement a vector that represents a list of TimedCallback objects who inherits from a base class.
They hold some basic variables, plus a function pointer which is the main feature.
The function should be able to return any type and have any params.
I pass them as lambdas into the functions, not really any problems so far.



This is the relevant code:



std::vector<std::unique_ptr<TimedCallbackBase>> m_TimerCallbackList;

struct TimedCallbackBase {
TimedCallbackBase() = default;
virtual ~TimedCallbackBase() = default;

template<typename T> T run()
{
return dynamic_cast< TimedCallback<T> & >(*this).Run();
}
template<typename T> std::string name()
{
return dynamic_cast< TimedCallback<T> & >(*this).Name;
}
template<typename T> TaskTimer time()
{
return dynamic_cast< TimedCallback<T> & >(*this).Time;
}
template<typename T> int repeatcount()
{
return dynamic_cast< TimedCallback<T> & >(*this).RepeatCount;
}
};

template <typename Fu>
struct TimedCallback : TimedCallbackBase {
TimedCallback(const std::string& name, const std::string& time, Fu f, int r) : Name(name), Run(f), Time(time), RepeatCount(r) {}
std::string Name;
Fu Run;
TaskTimer Time;
int RepeatCount;
};

template<typename Fu>
void Schedule(const std::string& name, const std::string& time, Fu f, int repeatCount = 0) {
TimedCallback cb(name, time, f, repeatCount);
if (!vec_contains(m_TimerCallbackList, cb)) {
m_TimerCallbackList.push_back(cb);
}
else { Global->Log->Warning(title(), "Callback '"+name+"' already exists."); }
}


My problem is this method. I am unable to properly run the func pointers.



void _RunTimers() {
if (m_TimerCallbackList.size() > 0) {
for (auto &t : m_TimerCallbackList) {
if (t != nullptr) {

std::string _name = t.get()->name(); // wrong syntax, or signature?
TaskTimer _time = t.get()->time();
int _repeatcount = t.get()->repeatcount();
//auto _run = t.get()->run(); ??

Global->t("Callback name: " + _name);
Global->t("Callback time: " + _time.GetRealTimeAsString());
Global->t("Callback count: " + its(_repeatcount));
}
}
}
else { Global->Log->Warning(title(), "No timed tasks to run at this time."); }
}


I intend to use the code like this:



Task->Schedule("testTimer", "10sec", [&]{ return Task->Test("I'm a 10sec timer."); });

_RunTimers();


I feel like I am pretty far from doing this correctly.
I don't want to specify any templates for the _RunTimers(); method.
Please help me understand how this can possible.



Edit:



I mean, I guess it is totally possible to just define a bunch of typedefs along the lines of



using int_func = std::function<int()>;


for every possible case and then overload my wrapper object, but I was looking for something more dynamic and change-proof.



Edit 2: After implementing the suggested changes



Note: I've renamed the methods for ambiguity's sake.
(The method Test() is not included here, but simply does a std::cout of a string param)



main:



Callback myCallback = make_callback(&TaskAssigner::Test, "I'm a 5sec timer.");

Task->ScheduleJob("timer1", "5sec", myCallback, -1);
Task->RunScheduledJobs();


Utilities:



typedef double RetVal;
typedef std::function<RetVal()> Callback;

template <class F, class... Args>
Callback make_callback(F&& f, Args&&... args)
{
auto callable = std::bind(f, args...); // Here we handle the parameters
return [callable]() -> RetVal{ return callable(); }; // Here we handle the return type
}

struct TimedCallback {
TimedCallback(cstR name, cstR time, Callback f, int r)
: Name(name), Run(f), Time(time), RepeatCount(r) {}

RetVal operator()() const { return Run(); }

bool operator==(const TimedCallback& other) {
if (Name == other.Name && RepeatCount == other.RepeatCount) { return true; }
return false;
}

const bool operator==(const TimedCallback& other) const {
if (Name == other.Name && RepeatCount == other.RepeatCount) { return true; }
return false;
}

std::string Name;
Callback Run;
TaskTimer Time;
int RepeatCount;
};


TaskAssigner .h:



void ScheduleJob(const std::string& name, const std::string& time, const Callback& func, int repeatCount = 0);

void RunScheduledJobs();

std::vector<TimedCallback> m_TimerCallbackList;


TaskAssigner.cpp:



void TaskAssigner::ScheduleJob(const std::string& name, const std::string& time, const Callback& func, int repeatCount) {

TimedCallback cb(name, time, func, repeatCount);

if (!vec_contains(m_TimerCallbackList, cb)) {
m_TimerCallbackList.emplace_back(cb);
}
else { Global->Log->Warning(title(), "Callback '" + name + "' already added."); }
}

void TaskAssigner::RunScheduledJobs() {
if (m_TimerCallbackList.size() > 0) {
for (auto &t : m_TimerCallbackList)
{
RetVal value = t();
//Global->t("Callback result: " + std::to_string(value));
Global->t("Callback name: " + t.Name);
Global->t("Callback time: " + t.Time.GetRealTimeAsString());
Global->t("Callback count: " + its(t.RepeatCount));
}
}
else { Global->Log->Warning(title(), "No timed tasks to run at this time."); }
}


Current problem:



Compiler says: C3848: expression having type 'const std::_Bind, const char(&)[18]>' would lose some const-volatile qualifiers in order to call .....



I tried researching and some have mentioned a bug with VS 2013 regarding bind and auto. Solutions include typing the signature rather than auto-ing it, or remove/add proper const(?). Not sure if this is the same bug or if my implementation is still incorrect.
(Bug: https://stackoverflow.com/a/30344737/8263197)



I am unsure how exactly I can make RetVal support any value with this typedef.
I tried



    template<typename T>
struct CallbackReturnValue {
CallbackReturnValue(T v) : value(v) {}
T value;
};


but then I will still need to template the other supporting methods. What am I mistaking here?










share|improve this question
























  • You never stated what the issue is. Is this a compiling issue? A runtime issue? A design issue?
    – PaulMcKenzie
    Nov 10 at 17:54










  • t.get()->name(); Doesn't work because compiler cannot deduce the template parameter for the function template template<typename T> std::string TimedCallbackBase::name(); . But I really don't see the point of the base class if every function just casts to the derive class. Did you do it to get rid of the template parameter in order to be able to store in the vector?
    – Quimby
    Nov 10 at 18:01










  • As written runtimers doesn't need the return value.
    – Yakk - Adam Nevraumont
    Nov 10 at 18:43










  • @PaulMcKenzie Pardon me. It's a compiling issue. I'm having problems understanding what the legal syntax is for what I want to achieve.
    – Mads Midtlyng
    Nov 11 at 6:23










  • @Quimby Exactly, I was trying to get rid of the template parameter so that the function which runs the list of callback-able objects doesn't have to be defined like that.
    – Mads Midtlyng
    Nov 12 at 4:50













up vote
1
down vote

favorite









up vote
1
down vote

favorite











I'm trying to implement a vector that represents a list of TimedCallback objects who inherits from a base class.
They hold some basic variables, plus a function pointer which is the main feature.
The function should be able to return any type and have any params.
I pass them as lambdas into the functions, not really any problems so far.



This is the relevant code:



std::vector<std::unique_ptr<TimedCallbackBase>> m_TimerCallbackList;

struct TimedCallbackBase {
TimedCallbackBase() = default;
virtual ~TimedCallbackBase() = default;

template<typename T> T run()
{
return dynamic_cast< TimedCallback<T> & >(*this).Run();
}
template<typename T> std::string name()
{
return dynamic_cast< TimedCallback<T> & >(*this).Name;
}
template<typename T> TaskTimer time()
{
return dynamic_cast< TimedCallback<T> & >(*this).Time;
}
template<typename T> int repeatcount()
{
return dynamic_cast< TimedCallback<T> & >(*this).RepeatCount;
}
};

template <typename Fu>
struct TimedCallback : TimedCallbackBase {
TimedCallback(const std::string& name, const std::string& time, Fu f, int r) : Name(name), Run(f), Time(time), RepeatCount(r) {}
std::string Name;
Fu Run;
TaskTimer Time;
int RepeatCount;
};

template<typename Fu>
void Schedule(const std::string& name, const std::string& time, Fu f, int repeatCount = 0) {
TimedCallback cb(name, time, f, repeatCount);
if (!vec_contains(m_TimerCallbackList, cb)) {
m_TimerCallbackList.push_back(cb);
}
else { Global->Log->Warning(title(), "Callback '"+name+"' already exists."); }
}


My problem is this method. I am unable to properly run the func pointers.



void _RunTimers() {
if (m_TimerCallbackList.size() > 0) {
for (auto &t : m_TimerCallbackList) {
if (t != nullptr) {

std::string _name = t.get()->name(); // wrong syntax, or signature?
TaskTimer _time = t.get()->time();
int _repeatcount = t.get()->repeatcount();
//auto _run = t.get()->run(); ??

Global->t("Callback name: " + _name);
Global->t("Callback time: " + _time.GetRealTimeAsString());
Global->t("Callback count: " + its(_repeatcount));
}
}
}
else { Global->Log->Warning(title(), "No timed tasks to run at this time."); }
}


I intend to use the code like this:



Task->Schedule("testTimer", "10sec", [&]{ return Task->Test("I'm a 10sec timer."); });

_RunTimers();


I feel like I am pretty far from doing this correctly.
I don't want to specify any templates for the _RunTimers(); method.
Please help me understand how this can possible.



Edit:



I mean, I guess it is totally possible to just define a bunch of typedefs along the lines of



using int_func = std::function<int()>;


for every possible case and then overload my wrapper object, but I was looking for something more dynamic and change-proof.



Edit 2: After implementing the suggested changes



Note: I've renamed the methods for ambiguity's sake.
(The method Test() is not included here, but simply does a std::cout of a string param)



main:



Callback myCallback = make_callback(&TaskAssigner::Test, "I'm a 5sec timer.");

Task->ScheduleJob("timer1", "5sec", myCallback, -1);
Task->RunScheduledJobs();


Utilities:



typedef double RetVal;
typedef std::function<RetVal()> Callback;

template <class F, class... Args>
Callback make_callback(F&& f, Args&&... args)
{
auto callable = std::bind(f, args...); // Here we handle the parameters
return [callable]() -> RetVal{ return callable(); }; // Here we handle the return type
}

struct TimedCallback {
TimedCallback(cstR name, cstR time, Callback f, int r)
: Name(name), Run(f), Time(time), RepeatCount(r) {}

RetVal operator()() const { return Run(); }

bool operator==(const TimedCallback& other) {
if (Name == other.Name && RepeatCount == other.RepeatCount) { return true; }
return false;
}

const bool operator==(const TimedCallback& other) const {
if (Name == other.Name && RepeatCount == other.RepeatCount) { return true; }
return false;
}

std::string Name;
Callback Run;
TaskTimer Time;
int RepeatCount;
};


TaskAssigner .h:



void ScheduleJob(const std::string& name, const std::string& time, const Callback& func, int repeatCount = 0);

void RunScheduledJobs();

std::vector<TimedCallback> m_TimerCallbackList;


TaskAssigner.cpp:



void TaskAssigner::ScheduleJob(const std::string& name, const std::string& time, const Callback& func, int repeatCount) {

TimedCallback cb(name, time, func, repeatCount);

if (!vec_contains(m_TimerCallbackList, cb)) {
m_TimerCallbackList.emplace_back(cb);
}
else { Global->Log->Warning(title(), "Callback '" + name + "' already added."); }
}

void TaskAssigner::RunScheduledJobs() {
if (m_TimerCallbackList.size() > 0) {
for (auto &t : m_TimerCallbackList)
{
RetVal value = t();
//Global->t("Callback result: " + std::to_string(value));
Global->t("Callback name: " + t.Name);
Global->t("Callback time: " + t.Time.GetRealTimeAsString());
Global->t("Callback count: " + its(t.RepeatCount));
}
}
else { Global->Log->Warning(title(), "No timed tasks to run at this time."); }
}


Current problem:



Compiler says: C3848: expression having type 'const std::_Bind, const char(&)[18]>' would lose some const-volatile qualifiers in order to call .....



I tried researching and some have mentioned a bug with VS 2013 regarding bind and auto. Solutions include typing the signature rather than auto-ing it, or remove/add proper const(?). Not sure if this is the same bug or if my implementation is still incorrect.
(Bug: https://stackoverflow.com/a/30344737/8263197)



I am unsure how exactly I can make RetVal support any value with this typedef.
I tried



    template<typename T>
struct CallbackReturnValue {
CallbackReturnValue(T v) : value(v) {}
T value;
};


but then I will still need to template the other supporting methods. What am I mistaking here?










share|improve this question















I'm trying to implement a vector that represents a list of TimedCallback objects who inherits from a base class.
They hold some basic variables, plus a function pointer which is the main feature.
The function should be able to return any type and have any params.
I pass them as lambdas into the functions, not really any problems so far.



This is the relevant code:



std::vector<std::unique_ptr<TimedCallbackBase>> m_TimerCallbackList;

struct TimedCallbackBase {
TimedCallbackBase() = default;
virtual ~TimedCallbackBase() = default;

template<typename T> T run()
{
return dynamic_cast< TimedCallback<T> & >(*this).Run();
}
template<typename T> std::string name()
{
return dynamic_cast< TimedCallback<T> & >(*this).Name;
}
template<typename T> TaskTimer time()
{
return dynamic_cast< TimedCallback<T> & >(*this).Time;
}
template<typename T> int repeatcount()
{
return dynamic_cast< TimedCallback<T> & >(*this).RepeatCount;
}
};

template <typename Fu>
struct TimedCallback : TimedCallbackBase {
TimedCallback(const std::string& name, const std::string& time, Fu f, int r) : Name(name), Run(f), Time(time), RepeatCount(r) {}
std::string Name;
Fu Run;
TaskTimer Time;
int RepeatCount;
};

template<typename Fu>
void Schedule(const std::string& name, const std::string& time, Fu f, int repeatCount = 0) {
TimedCallback cb(name, time, f, repeatCount);
if (!vec_contains(m_TimerCallbackList, cb)) {
m_TimerCallbackList.push_back(cb);
}
else { Global->Log->Warning(title(), "Callback '"+name+"' already exists."); }
}


My problem is this method. I am unable to properly run the func pointers.



void _RunTimers() {
if (m_TimerCallbackList.size() > 0) {
for (auto &t : m_TimerCallbackList) {
if (t != nullptr) {

std::string _name = t.get()->name(); // wrong syntax, or signature?
TaskTimer _time = t.get()->time();
int _repeatcount = t.get()->repeatcount();
//auto _run = t.get()->run(); ??

Global->t("Callback name: " + _name);
Global->t("Callback time: " + _time.GetRealTimeAsString());
Global->t("Callback count: " + its(_repeatcount));
}
}
}
else { Global->Log->Warning(title(), "No timed tasks to run at this time."); }
}


I intend to use the code like this:



Task->Schedule("testTimer", "10sec", [&]{ return Task->Test("I'm a 10sec timer."); });

_RunTimers();


I feel like I am pretty far from doing this correctly.
I don't want to specify any templates for the _RunTimers(); method.
Please help me understand how this can possible.



Edit:



I mean, I guess it is totally possible to just define a bunch of typedefs along the lines of



using int_func = std::function<int()>;


for every possible case and then overload my wrapper object, but I was looking for something more dynamic and change-proof.



Edit 2: After implementing the suggested changes



Note: I've renamed the methods for ambiguity's sake.
(The method Test() is not included here, but simply does a std::cout of a string param)



main:



Callback myCallback = make_callback(&TaskAssigner::Test, "I'm a 5sec timer.");

Task->ScheduleJob("timer1", "5sec", myCallback, -1);
Task->RunScheduledJobs();


Utilities:



typedef double RetVal;
typedef std::function<RetVal()> Callback;

template <class F, class... Args>
Callback make_callback(F&& f, Args&&... args)
{
auto callable = std::bind(f, args...); // Here we handle the parameters
return [callable]() -> RetVal{ return callable(); }; // Here we handle the return type
}

struct TimedCallback {
TimedCallback(cstR name, cstR time, Callback f, int r)
: Name(name), Run(f), Time(time), RepeatCount(r) {}

RetVal operator()() const { return Run(); }

bool operator==(const TimedCallback& other) {
if (Name == other.Name && RepeatCount == other.RepeatCount) { return true; }
return false;
}

const bool operator==(const TimedCallback& other) const {
if (Name == other.Name && RepeatCount == other.RepeatCount) { return true; }
return false;
}

std::string Name;
Callback Run;
TaskTimer Time;
int RepeatCount;
};


TaskAssigner .h:



void ScheduleJob(const std::string& name, const std::string& time, const Callback& func, int repeatCount = 0);

void RunScheduledJobs();

std::vector<TimedCallback> m_TimerCallbackList;


TaskAssigner.cpp:



void TaskAssigner::ScheduleJob(const std::string& name, const std::string& time, const Callback& func, int repeatCount) {

TimedCallback cb(name, time, func, repeatCount);

if (!vec_contains(m_TimerCallbackList, cb)) {
m_TimerCallbackList.emplace_back(cb);
}
else { Global->Log->Warning(title(), "Callback '" + name + "' already added."); }
}

void TaskAssigner::RunScheduledJobs() {
if (m_TimerCallbackList.size() > 0) {
for (auto &t : m_TimerCallbackList)
{
RetVal value = t();
//Global->t("Callback result: " + std::to_string(value));
Global->t("Callback name: " + t.Name);
Global->t("Callback time: " + t.Time.GetRealTimeAsString());
Global->t("Callback count: " + its(t.RepeatCount));
}
}
else { Global->Log->Warning(title(), "No timed tasks to run at this time."); }
}


Current problem:



Compiler says: C3848: expression having type 'const std::_Bind, const char(&)[18]>' would lose some const-volatile qualifiers in order to call .....



I tried researching and some have mentioned a bug with VS 2013 regarding bind and auto. Solutions include typing the signature rather than auto-ing it, or remove/add proper const(?). Not sure if this is the same bug or if my implementation is still incorrect.
(Bug: https://stackoverflow.com/a/30344737/8263197)



I am unsure how exactly I can make RetVal support any value with this typedef.
I tried



    template<typename T>
struct CallbackReturnValue {
CallbackReturnValue(T v) : value(v) {}
T value;
};


but then I will still need to template the other supporting methods. What am I mistaking here?







c++ templates vector polymorphism






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 12 at 14:18

























asked Nov 10 at 17:38









Mads Midtlyng

567




567












  • You never stated what the issue is. Is this a compiling issue? A runtime issue? A design issue?
    – PaulMcKenzie
    Nov 10 at 17:54










  • t.get()->name(); Doesn't work because compiler cannot deduce the template parameter for the function template template<typename T> std::string TimedCallbackBase::name(); . But I really don't see the point of the base class if every function just casts to the derive class. Did you do it to get rid of the template parameter in order to be able to store in the vector?
    – Quimby
    Nov 10 at 18:01










  • As written runtimers doesn't need the return value.
    – Yakk - Adam Nevraumont
    Nov 10 at 18:43










  • @PaulMcKenzie Pardon me. It's a compiling issue. I'm having problems understanding what the legal syntax is for what I want to achieve.
    – Mads Midtlyng
    Nov 11 at 6:23










  • @Quimby Exactly, I was trying to get rid of the template parameter so that the function which runs the list of callback-able objects doesn't have to be defined like that.
    – Mads Midtlyng
    Nov 12 at 4:50


















  • You never stated what the issue is. Is this a compiling issue? A runtime issue? A design issue?
    – PaulMcKenzie
    Nov 10 at 17:54










  • t.get()->name(); Doesn't work because compiler cannot deduce the template parameter for the function template template<typename T> std::string TimedCallbackBase::name(); . But I really don't see the point of the base class if every function just casts to the derive class. Did you do it to get rid of the template parameter in order to be able to store in the vector?
    – Quimby
    Nov 10 at 18:01










  • As written runtimers doesn't need the return value.
    – Yakk - Adam Nevraumont
    Nov 10 at 18:43










  • @PaulMcKenzie Pardon me. It's a compiling issue. I'm having problems understanding what the legal syntax is for what I want to achieve.
    – Mads Midtlyng
    Nov 11 at 6:23










  • @Quimby Exactly, I was trying to get rid of the template parameter so that the function which runs the list of callback-able objects doesn't have to be defined like that.
    – Mads Midtlyng
    Nov 12 at 4:50
















You never stated what the issue is. Is this a compiling issue? A runtime issue? A design issue?
– PaulMcKenzie
Nov 10 at 17:54




You never stated what the issue is. Is this a compiling issue? A runtime issue? A design issue?
– PaulMcKenzie
Nov 10 at 17:54












t.get()->name(); Doesn't work because compiler cannot deduce the template parameter for the function template template<typename T> std::string TimedCallbackBase::name(); . But I really don't see the point of the base class if every function just casts to the derive class. Did you do it to get rid of the template parameter in order to be able to store in the vector?
– Quimby
Nov 10 at 18:01




t.get()->name(); Doesn't work because compiler cannot deduce the template parameter for the function template template<typename T> std::string TimedCallbackBase::name(); . But I really don't see the point of the base class if every function just casts to the derive class. Did you do it to get rid of the template parameter in order to be able to store in the vector?
– Quimby
Nov 10 at 18:01












As written runtimers doesn't need the return value.
– Yakk - Adam Nevraumont
Nov 10 at 18:43




As written runtimers doesn't need the return value.
– Yakk - Adam Nevraumont
Nov 10 at 18:43












@PaulMcKenzie Pardon me. It's a compiling issue. I'm having problems understanding what the legal syntax is for what I want to achieve.
– Mads Midtlyng
Nov 11 at 6:23




@PaulMcKenzie Pardon me. It's a compiling issue. I'm having problems understanding what the legal syntax is for what I want to achieve.
– Mads Midtlyng
Nov 11 at 6:23












@Quimby Exactly, I was trying to get rid of the template parameter so that the function which runs the list of callback-able objects doesn't have to be defined like that.
– Mads Midtlyng
Nov 12 at 4:50




@Quimby Exactly, I was trying to get rid of the template parameter so that the function which runs the list of callback-able objects doesn't have to be defined like that.
– Mads Midtlyng
Nov 12 at 4:50












1 Answer
1






active

oldest

votes

















up vote
2
down vote













It seems like you are trying to re-invent std::function ("a general-purpose polymorphic function wrapper"). Instead of dealing with templates and multiple child classes, I would try something more like the following.



typedef std::function<void()> Callback;

struct TimedCallback {
TimedCallback(const std::string& name, const std::string& time, const Callback & f, int r) :
Name(name),
Run(f),
Time(time),
RepeatCount(r)
{}

// Not wise to differentiate names by case (run vs. Run),
// but this form might be instructive as to how this
// setup would fit into your existing _RunTimers().
// By the way, _RunTimers is a reserved identifier.
void run()
{
Run();
}

std::string Name;
Callback Run;
TaskTimer Time;
int RepeatCount;
};


Something more complex would be needed if you need the values returned by the callbacks. However, try taking this one step at a time.





After some clarifications, it seems the intent is to store returned values in some sort of container. To make this work, there would need to be a type that all returned values can be converted to (such as having all returned values be classes derived from a common base class). I'll proceed to give one way this could be made to work.



The first step is to define the common return type. By making this a typedef, I can abstract away this choice in later code.



typedef /* fill this in */ RetVal;


Next, we revise the definition of Callback and run() to account for this type.



typedef std::function<RetVal()> Callback;

RetVal run()
{
return Run();
}


The definition of TimedCallback otherwise remains the same, but I would introduce a convenience layer to make it easier to construct these callbacks. Inspired by such awe-inspiring names as "make_pair" and "make_tuple":



template <class F, class... Args>
Callback make_callback(F&& f, Args&&... args)
{
auto callable = std::bind(f, args...); // Here we handle the parameters
return [callable]() -> RetVal{ return callable(); }; // Here we handle the return type
}


Ah, templates have finally made an appearance! But note that the template is localized to this convenience function; you don't necessarily need to use this template if your callable object is already in a convenient form. Assuming the object is not in a convenient form, here is a sample use of the convenience. For the sake of example, I am going to assume that a string is implicitly convertible to RetVal.



// Example function that takes a parameter.
std::string hello(const std::string & world)
{
std::cout << "Hello " << world << "!n";
return world;
}

// Example main function to see that this can work.
int main()
{
// Placeholder for m_TimerCallbackList.
std::vector<TimedCallback> timer_list;

// Instead of Task->Schedule(), I'll emplace on a vector.
timer_list.emplace_back("testTimer", "10sec",
make_callback(hello, "Earth"),
1);

// Instead of RunTimers(), I'll manually run the first callback.
RetVal value = timer_list[0].run();
}





share|improve this answer























  • Thanks for the comment. I was under the impression that for this typedef, I can only add TimedCallback objects with a ' void func()' signature? I want to be able to add any type such as 'bool func()' or 'int func(string)' etc. Please correct me if I'm wrong.
    – Mads Midtlyng
    Nov 11 at 6:24












  • @MadsMidtlyng Since you are using lambdas, why do you need them to return anything? You are not using the returned value when you run the timers. As for parameters, see the examples in my link for std::function, particularly the ones that use std::bind. It can be made to work. (Maybe if you had more examples of the cases you need to handle?)
    – JaMiT
    Nov 11 at 6:31












  • Basically, what I want to do is define a custom job and add it to a list. The job has a timer, name and a function. The jobs are run according to their time in a loop, so if the function has a return value, it should be possible to obtain it. The function should be any type with variable arguments, e.g. 'ReturnType myFunc(Args... arguments)', so it can work the same if the passed function is 'void func()' or 'int calcFunc(a, b)' Does that make sense?
    – Mads Midtlyng
    Nov 12 at 4:36












  • @MadsMidtlyng How would the return value be obtained? Is RunTimers going to know what to do with the returned value? I haven't worried about the returned values because when you have callbacks, there is usually no good way to make use of returned values.
    – JaMiT
    Nov 12 at 4:45










  • I was thinking of adding them to another vector that collects them during the _RunTimers() method. I think in my case the return values will work fine as simple types and no custom classes. Is it unfeasible?
    – Mads Midtlyng
    Nov 12 at 4:47











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53241666%2fvector-with-objects-that-have-function-pointers-of-varying-type%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote













It seems like you are trying to re-invent std::function ("a general-purpose polymorphic function wrapper"). Instead of dealing with templates and multiple child classes, I would try something more like the following.



typedef std::function<void()> Callback;

struct TimedCallback {
TimedCallback(const std::string& name, const std::string& time, const Callback & f, int r) :
Name(name),
Run(f),
Time(time),
RepeatCount(r)
{}

// Not wise to differentiate names by case (run vs. Run),
// but this form might be instructive as to how this
// setup would fit into your existing _RunTimers().
// By the way, _RunTimers is a reserved identifier.
void run()
{
Run();
}

std::string Name;
Callback Run;
TaskTimer Time;
int RepeatCount;
};


Something more complex would be needed if you need the values returned by the callbacks. However, try taking this one step at a time.





After some clarifications, it seems the intent is to store returned values in some sort of container. To make this work, there would need to be a type that all returned values can be converted to (such as having all returned values be classes derived from a common base class). I'll proceed to give one way this could be made to work.



The first step is to define the common return type. By making this a typedef, I can abstract away this choice in later code.



typedef /* fill this in */ RetVal;


Next, we revise the definition of Callback and run() to account for this type.



typedef std::function<RetVal()> Callback;

RetVal run()
{
return Run();
}


The definition of TimedCallback otherwise remains the same, but I would introduce a convenience layer to make it easier to construct these callbacks. Inspired by such awe-inspiring names as "make_pair" and "make_tuple":



template <class F, class... Args>
Callback make_callback(F&& f, Args&&... args)
{
auto callable = std::bind(f, args...); // Here we handle the parameters
return [callable]() -> RetVal{ return callable(); }; // Here we handle the return type
}


Ah, templates have finally made an appearance! But note that the template is localized to this convenience function; you don't necessarily need to use this template if your callable object is already in a convenient form. Assuming the object is not in a convenient form, here is a sample use of the convenience. For the sake of example, I am going to assume that a string is implicitly convertible to RetVal.



// Example function that takes a parameter.
std::string hello(const std::string & world)
{
std::cout << "Hello " << world << "!n";
return world;
}

// Example main function to see that this can work.
int main()
{
// Placeholder for m_TimerCallbackList.
std::vector<TimedCallback> timer_list;

// Instead of Task->Schedule(), I'll emplace on a vector.
timer_list.emplace_back("testTimer", "10sec",
make_callback(hello, "Earth"),
1);

// Instead of RunTimers(), I'll manually run the first callback.
RetVal value = timer_list[0].run();
}





share|improve this answer























  • Thanks for the comment. I was under the impression that for this typedef, I can only add TimedCallback objects with a ' void func()' signature? I want to be able to add any type such as 'bool func()' or 'int func(string)' etc. Please correct me if I'm wrong.
    – Mads Midtlyng
    Nov 11 at 6:24












  • @MadsMidtlyng Since you are using lambdas, why do you need them to return anything? You are not using the returned value when you run the timers. As for parameters, see the examples in my link for std::function, particularly the ones that use std::bind. It can be made to work. (Maybe if you had more examples of the cases you need to handle?)
    – JaMiT
    Nov 11 at 6:31












  • Basically, what I want to do is define a custom job and add it to a list. The job has a timer, name and a function. The jobs are run according to their time in a loop, so if the function has a return value, it should be possible to obtain it. The function should be any type with variable arguments, e.g. 'ReturnType myFunc(Args... arguments)', so it can work the same if the passed function is 'void func()' or 'int calcFunc(a, b)' Does that make sense?
    – Mads Midtlyng
    Nov 12 at 4:36












  • @MadsMidtlyng How would the return value be obtained? Is RunTimers going to know what to do with the returned value? I haven't worried about the returned values because when you have callbacks, there is usually no good way to make use of returned values.
    – JaMiT
    Nov 12 at 4:45










  • I was thinking of adding them to another vector that collects them during the _RunTimers() method. I think in my case the return values will work fine as simple types and no custom classes. Is it unfeasible?
    – Mads Midtlyng
    Nov 12 at 4:47















up vote
2
down vote













It seems like you are trying to re-invent std::function ("a general-purpose polymorphic function wrapper"). Instead of dealing with templates and multiple child classes, I would try something more like the following.



typedef std::function<void()> Callback;

struct TimedCallback {
TimedCallback(const std::string& name, const std::string& time, const Callback & f, int r) :
Name(name),
Run(f),
Time(time),
RepeatCount(r)
{}

// Not wise to differentiate names by case (run vs. Run),
// but this form might be instructive as to how this
// setup would fit into your existing _RunTimers().
// By the way, _RunTimers is a reserved identifier.
void run()
{
Run();
}

std::string Name;
Callback Run;
TaskTimer Time;
int RepeatCount;
};


Something more complex would be needed if you need the values returned by the callbacks. However, try taking this one step at a time.





After some clarifications, it seems the intent is to store returned values in some sort of container. To make this work, there would need to be a type that all returned values can be converted to (such as having all returned values be classes derived from a common base class). I'll proceed to give one way this could be made to work.



The first step is to define the common return type. By making this a typedef, I can abstract away this choice in later code.



typedef /* fill this in */ RetVal;


Next, we revise the definition of Callback and run() to account for this type.



typedef std::function<RetVal()> Callback;

RetVal run()
{
return Run();
}


The definition of TimedCallback otherwise remains the same, but I would introduce a convenience layer to make it easier to construct these callbacks. Inspired by such awe-inspiring names as "make_pair" and "make_tuple":



template <class F, class... Args>
Callback make_callback(F&& f, Args&&... args)
{
auto callable = std::bind(f, args...); // Here we handle the parameters
return [callable]() -> RetVal{ return callable(); }; // Here we handle the return type
}


Ah, templates have finally made an appearance! But note that the template is localized to this convenience function; you don't necessarily need to use this template if your callable object is already in a convenient form. Assuming the object is not in a convenient form, here is a sample use of the convenience. For the sake of example, I am going to assume that a string is implicitly convertible to RetVal.



// Example function that takes a parameter.
std::string hello(const std::string & world)
{
std::cout << "Hello " << world << "!n";
return world;
}

// Example main function to see that this can work.
int main()
{
// Placeholder for m_TimerCallbackList.
std::vector<TimedCallback> timer_list;

// Instead of Task->Schedule(), I'll emplace on a vector.
timer_list.emplace_back("testTimer", "10sec",
make_callback(hello, "Earth"),
1);

// Instead of RunTimers(), I'll manually run the first callback.
RetVal value = timer_list[0].run();
}





share|improve this answer























  • Thanks for the comment. I was under the impression that for this typedef, I can only add TimedCallback objects with a ' void func()' signature? I want to be able to add any type such as 'bool func()' or 'int func(string)' etc. Please correct me if I'm wrong.
    – Mads Midtlyng
    Nov 11 at 6:24












  • @MadsMidtlyng Since you are using lambdas, why do you need them to return anything? You are not using the returned value when you run the timers. As for parameters, see the examples in my link for std::function, particularly the ones that use std::bind. It can be made to work. (Maybe if you had more examples of the cases you need to handle?)
    – JaMiT
    Nov 11 at 6:31












  • Basically, what I want to do is define a custom job and add it to a list. The job has a timer, name and a function. The jobs are run according to their time in a loop, so if the function has a return value, it should be possible to obtain it. The function should be any type with variable arguments, e.g. 'ReturnType myFunc(Args... arguments)', so it can work the same if the passed function is 'void func()' or 'int calcFunc(a, b)' Does that make sense?
    – Mads Midtlyng
    Nov 12 at 4:36












  • @MadsMidtlyng How would the return value be obtained? Is RunTimers going to know what to do with the returned value? I haven't worried about the returned values because when you have callbacks, there is usually no good way to make use of returned values.
    – JaMiT
    Nov 12 at 4:45










  • I was thinking of adding them to another vector that collects them during the _RunTimers() method. I think in my case the return values will work fine as simple types and no custom classes. Is it unfeasible?
    – Mads Midtlyng
    Nov 12 at 4:47













up vote
2
down vote










up vote
2
down vote









It seems like you are trying to re-invent std::function ("a general-purpose polymorphic function wrapper"). Instead of dealing with templates and multiple child classes, I would try something more like the following.



typedef std::function<void()> Callback;

struct TimedCallback {
TimedCallback(const std::string& name, const std::string& time, const Callback & f, int r) :
Name(name),
Run(f),
Time(time),
RepeatCount(r)
{}

// Not wise to differentiate names by case (run vs. Run),
// but this form might be instructive as to how this
// setup would fit into your existing _RunTimers().
// By the way, _RunTimers is a reserved identifier.
void run()
{
Run();
}

std::string Name;
Callback Run;
TaskTimer Time;
int RepeatCount;
};


Something more complex would be needed if you need the values returned by the callbacks. However, try taking this one step at a time.





After some clarifications, it seems the intent is to store returned values in some sort of container. To make this work, there would need to be a type that all returned values can be converted to (such as having all returned values be classes derived from a common base class). I'll proceed to give one way this could be made to work.



The first step is to define the common return type. By making this a typedef, I can abstract away this choice in later code.



typedef /* fill this in */ RetVal;


Next, we revise the definition of Callback and run() to account for this type.



typedef std::function<RetVal()> Callback;

RetVal run()
{
return Run();
}


The definition of TimedCallback otherwise remains the same, but I would introduce a convenience layer to make it easier to construct these callbacks. Inspired by such awe-inspiring names as "make_pair" and "make_tuple":



template <class F, class... Args>
Callback make_callback(F&& f, Args&&... args)
{
auto callable = std::bind(f, args...); // Here we handle the parameters
return [callable]() -> RetVal{ return callable(); }; // Here we handle the return type
}


Ah, templates have finally made an appearance! But note that the template is localized to this convenience function; you don't necessarily need to use this template if your callable object is already in a convenient form. Assuming the object is not in a convenient form, here is a sample use of the convenience. For the sake of example, I am going to assume that a string is implicitly convertible to RetVal.



// Example function that takes a parameter.
std::string hello(const std::string & world)
{
std::cout << "Hello " << world << "!n";
return world;
}

// Example main function to see that this can work.
int main()
{
// Placeholder for m_TimerCallbackList.
std::vector<TimedCallback> timer_list;

// Instead of Task->Schedule(), I'll emplace on a vector.
timer_list.emplace_back("testTimer", "10sec",
make_callback(hello, "Earth"),
1);

// Instead of RunTimers(), I'll manually run the first callback.
RetVal value = timer_list[0].run();
}





share|improve this answer














It seems like you are trying to re-invent std::function ("a general-purpose polymorphic function wrapper"). Instead of dealing with templates and multiple child classes, I would try something more like the following.



typedef std::function<void()> Callback;

struct TimedCallback {
TimedCallback(const std::string& name, const std::string& time, const Callback & f, int r) :
Name(name),
Run(f),
Time(time),
RepeatCount(r)
{}

// Not wise to differentiate names by case (run vs. Run),
// but this form might be instructive as to how this
// setup would fit into your existing _RunTimers().
// By the way, _RunTimers is a reserved identifier.
void run()
{
Run();
}

std::string Name;
Callback Run;
TaskTimer Time;
int RepeatCount;
};


Something more complex would be needed if you need the values returned by the callbacks. However, try taking this one step at a time.





After some clarifications, it seems the intent is to store returned values in some sort of container. To make this work, there would need to be a type that all returned values can be converted to (such as having all returned values be classes derived from a common base class). I'll proceed to give one way this could be made to work.



The first step is to define the common return type. By making this a typedef, I can abstract away this choice in later code.



typedef /* fill this in */ RetVal;


Next, we revise the definition of Callback and run() to account for this type.



typedef std::function<RetVal()> Callback;

RetVal run()
{
return Run();
}


The definition of TimedCallback otherwise remains the same, but I would introduce a convenience layer to make it easier to construct these callbacks. Inspired by such awe-inspiring names as "make_pair" and "make_tuple":



template <class F, class... Args>
Callback make_callback(F&& f, Args&&... args)
{
auto callable = std::bind(f, args...); // Here we handle the parameters
return [callable]() -> RetVal{ return callable(); }; // Here we handle the return type
}


Ah, templates have finally made an appearance! But note that the template is localized to this convenience function; you don't necessarily need to use this template if your callable object is already in a convenient form. Assuming the object is not in a convenient form, here is a sample use of the convenience. For the sake of example, I am going to assume that a string is implicitly convertible to RetVal.



// Example function that takes a parameter.
std::string hello(const std::string & world)
{
std::cout << "Hello " << world << "!n";
return world;
}

// Example main function to see that this can work.
int main()
{
// Placeholder for m_TimerCallbackList.
std::vector<TimedCallback> timer_list;

// Instead of Task->Schedule(), I'll emplace on a vector.
timer_list.emplace_back("testTimer", "10sec",
make_callback(hello, "Earth"),
1);

// Instead of RunTimers(), I'll manually run the first callback.
RetVal value = timer_list[0].run();
}






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 12 at 5:57

























answered Nov 11 at 1:24









JaMiT

87211




87211












  • Thanks for the comment. I was under the impression that for this typedef, I can only add TimedCallback objects with a ' void func()' signature? I want to be able to add any type such as 'bool func()' or 'int func(string)' etc. Please correct me if I'm wrong.
    – Mads Midtlyng
    Nov 11 at 6:24












  • @MadsMidtlyng Since you are using lambdas, why do you need them to return anything? You are not using the returned value when you run the timers. As for parameters, see the examples in my link for std::function, particularly the ones that use std::bind. It can be made to work. (Maybe if you had more examples of the cases you need to handle?)
    – JaMiT
    Nov 11 at 6:31












  • Basically, what I want to do is define a custom job and add it to a list. The job has a timer, name and a function. The jobs are run according to their time in a loop, so if the function has a return value, it should be possible to obtain it. The function should be any type with variable arguments, e.g. 'ReturnType myFunc(Args... arguments)', so it can work the same if the passed function is 'void func()' or 'int calcFunc(a, b)' Does that make sense?
    – Mads Midtlyng
    Nov 12 at 4:36












  • @MadsMidtlyng How would the return value be obtained? Is RunTimers going to know what to do with the returned value? I haven't worried about the returned values because when you have callbacks, there is usually no good way to make use of returned values.
    – JaMiT
    Nov 12 at 4:45










  • I was thinking of adding them to another vector that collects them during the _RunTimers() method. I think in my case the return values will work fine as simple types and no custom classes. Is it unfeasible?
    – Mads Midtlyng
    Nov 12 at 4:47


















  • Thanks for the comment. I was under the impression that for this typedef, I can only add TimedCallback objects with a ' void func()' signature? I want to be able to add any type such as 'bool func()' or 'int func(string)' etc. Please correct me if I'm wrong.
    – Mads Midtlyng
    Nov 11 at 6:24












  • @MadsMidtlyng Since you are using lambdas, why do you need them to return anything? You are not using the returned value when you run the timers. As for parameters, see the examples in my link for std::function, particularly the ones that use std::bind. It can be made to work. (Maybe if you had more examples of the cases you need to handle?)
    – JaMiT
    Nov 11 at 6:31












  • Basically, what I want to do is define a custom job and add it to a list. The job has a timer, name and a function. The jobs are run according to their time in a loop, so if the function has a return value, it should be possible to obtain it. The function should be any type with variable arguments, e.g. 'ReturnType myFunc(Args... arguments)', so it can work the same if the passed function is 'void func()' or 'int calcFunc(a, b)' Does that make sense?
    – Mads Midtlyng
    Nov 12 at 4:36












  • @MadsMidtlyng How would the return value be obtained? Is RunTimers going to know what to do with the returned value? I haven't worried about the returned values because when you have callbacks, there is usually no good way to make use of returned values.
    – JaMiT
    Nov 12 at 4:45










  • I was thinking of adding them to another vector that collects them during the _RunTimers() method. I think in my case the return values will work fine as simple types and no custom classes. Is it unfeasible?
    – Mads Midtlyng
    Nov 12 at 4:47
















Thanks for the comment. I was under the impression that for this typedef, I can only add TimedCallback objects with a ' void func()' signature? I want to be able to add any type such as 'bool func()' or 'int func(string)' etc. Please correct me if I'm wrong.
– Mads Midtlyng
Nov 11 at 6:24






Thanks for the comment. I was under the impression that for this typedef, I can only add TimedCallback objects with a ' void func()' signature? I want to be able to add any type such as 'bool func()' or 'int func(string)' etc. Please correct me if I'm wrong.
– Mads Midtlyng
Nov 11 at 6:24














@MadsMidtlyng Since you are using lambdas, why do you need them to return anything? You are not using the returned value when you run the timers. As for parameters, see the examples in my link for std::function, particularly the ones that use std::bind. It can be made to work. (Maybe if you had more examples of the cases you need to handle?)
– JaMiT
Nov 11 at 6:31






@MadsMidtlyng Since you are using lambdas, why do you need them to return anything? You are not using the returned value when you run the timers. As for parameters, see the examples in my link for std::function, particularly the ones that use std::bind. It can be made to work. (Maybe if you had more examples of the cases you need to handle?)
– JaMiT
Nov 11 at 6:31














Basically, what I want to do is define a custom job and add it to a list. The job has a timer, name and a function. The jobs are run according to their time in a loop, so if the function has a return value, it should be possible to obtain it. The function should be any type with variable arguments, e.g. 'ReturnType myFunc(Args... arguments)', so it can work the same if the passed function is 'void func()' or 'int calcFunc(a, b)' Does that make sense?
– Mads Midtlyng
Nov 12 at 4:36






Basically, what I want to do is define a custom job and add it to a list. The job has a timer, name and a function. The jobs are run according to their time in a loop, so if the function has a return value, it should be possible to obtain it. The function should be any type with variable arguments, e.g. 'ReturnType myFunc(Args... arguments)', so it can work the same if the passed function is 'void func()' or 'int calcFunc(a, b)' Does that make sense?
– Mads Midtlyng
Nov 12 at 4:36














@MadsMidtlyng How would the return value be obtained? Is RunTimers going to know what to do with the returned value? I haven't worried about the returned values because when you have callbacks, there is usually no good way to make use of returned values.
– JaMiT
Nov 12 at 4:45




@MadsMidtlyng How would the return value be obtained? Is RunTimers going to know what to do with the returned value? I haven't worried about the returned values because when you have callbacks, there is usually no good way to make use of returned values.
– JaMiT
Nov 12 at 4:45












I was thinking of adding them to another vector that collects them during the _RunTimers() method. I think in my case the return values will work fine as simple types and no custom classes. Is it unfeasible?
– Mads Midtlyng
Nov 12 at 4:47




I was thinking of adding them to another vector that collects them during the _RunTimers() method. I think in my case the return values will work fine as simple types and no custom classes. Is it unfeasible?
– Mads Midtlyng
Nov 12 at 4:47


















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53241666%2fvector-with-objects-that-have-function-pointers-of-varying-type%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Xamarin.iOS Cant Deploy on Iphone

Glorious Revolution

Dulmage-Mendelsohn matrix decomposition in Python