1

I want to create a function like setInterval(func, delay, [arg1, arg2, ...]); of JavaScript.

void func(int t) {
    std::cout<<t<<std::endl;
}

void func(int i, char* t) {
    std::cout<<t<<std::endl;
}

class Timer {
public:
    void setInterval(auto function, int interval, ...args);
};

void Timer::setInterval(auto function, int interval, ...args) {
    while(1) {
        function(args);
        msleep(interval);
    }
}

int main() {
    Timer *t1 = new Timer;
    t1->setInterval(func, 1000, 2021);

    Timer *t2 = new Timer;
    t2->setInterval(func, 1000, 2, "hello");

    while (1) {

    }
    return 0;
}

But I don't know how to convert variadic arguments to Class member function. Can anyone help me? Thank you.

4
  • Do you know how to do it for a non-member function? If yes, where exactly is the problem? There is no attempt in the shown code to use the variadic arguments correctly Commented Aug 10, 2021 at 8:57
  • Another issue is that func is an overloaded function, so you cannot take its address for auto. Commented Aug 10, 2021 at 9:01
  • You can use 'stdarg' for that. stackoverflow.com/a/1579732/8875520 Commented Aug 10, 2021 at 9:24
  • while (1) {} is UB. Commented Aug 10, 2021 at 12:00

2 Answers 2

2

You can do it by using template.

#include <iostream>
#include <thread>

class Timer 
{
public:
    template <typename T>
    void SetInterval(int interval, T t)
    {
        std::cout << t << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(interval));
    }

    template <typename T, typename... Types>
    void SetInterval(int interval, T t, Types... args)
    {
        SetInterval(interval, args...);
    }
};

int main() {
    Timer *t1 = new Timer;
    t1->SetInterval(1000, 2001);

    Timer *t2 = new Timer;
    t2->SetInterval(1000, 2, "hello");

    delete t1;
    delete t2;

    while (1) {

    }
    return 0;
}
Sign up to request clarification or add additional context in comments.

6 Comments

Better (for compile time) to avoid recursion and use folding expression: (std::cout << args), ...); std::cout << std::endl; /*..*/
No, only when the last parameter of args, sleep works.
I know that the folding expression is available from C++17, I am using c+11, and, the second call in ssroreo's code, the last parameter is only printed.
There are tricks to mimic fold expressions in C++11 (as const int dummy[] = {0, (f(ts), 0)...};).
Not sure it was not a OP's typo to print only the last parameter though ;-)
|
0

I suggest

class Timer
{
public:

    void setInterval(std::function<void()> f, std::chrono::milliseconds interval)
    // template <typename F> void setInterval(F f, std::chrono::milliseconds interval)
    {
        while (true) {
            f();
            std::this_threas::sleep_for(interval);
        }
    }
};

With calls similar to:

using namespace std::chrono_literals;

Timer t1;
t1.setInterval([](){ func(2021);}, 1000ms);

Timer().setInterval([](){ func(2, "hello");}, 1000ms);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.