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?
c++ templates vector polymorphism
add a comment |
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?
c++ templates vector polymorphism
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 templatetemplate<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
add a comment |
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?
c++ templates vector polymorphism
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
c++ templates vector polymorphism
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 templatetemplate<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
add a comment |
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 templatetemplate<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
add a comment |
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();
}
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 forstd::function
, particularly the ones that usestd::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? IsRunTimers
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
|
show 5 more comments
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();
}
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 forstd::function
, particularly the ones that usestd::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? IsRunTimers
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
|
show 5 more comments
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();
}
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 forstd::function
, particularly the ones that usestd::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? IsRunTimers
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
|
show 5 more comments
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();
}
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();
}
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 forstd::function
, particularly the ones that usestd::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? IsRunTimers
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
|
show 5 more comments
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 forstd::function
, particularly the ones that usestd::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? IsRunTimers
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
|
show 5 more comments
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 templatetemplate<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