dansam8
dansam8

Reputation: 43

Is this attempt at a more python style decorator in c++ reliable / safe

Coming to c++ from python, this is as close as I can get to a python like decorator.

This solution feels a bit like a hack because the code to be run after the function to be decorated, in the Timer destructor is call implicitly. It does work though.

My question is: Is this safe and reliable, or more specifically is the destructor of the Timer class guaranteed to be called directly after the function returns (the Timer instance going out of scope).

class Timer{
    time_t time;
    std::string name;
public:
    Timer(std::string name): name(name)
    {
        time = now();
    }
    ~Timer()
    {
        printf("time taken by \"%s\" was: %d\n", name.c_str(), (now() - time));
    }
};


void my_function(){
    Timer _(__func__);
    // function code
}

Upvotes: 1

Views: 125

Answers (2)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385264

Yep, that is a safe, reliable and conventional way to do this.

It kind of is a bit of a hack, because destructors are designed to do cleanup tasks rather than produce key output, but it's a hack that everybody uses and is happy with.

Well done!

Upvotes: 0

apple apple
apple apple

Reputation: 10604

First answer your question, yes it's safe.


I just write this, I think this more like python decorator (like you can change parameter).

*Not well tested, just demonstrate the idea.

#include <iostream>
#include <chrono>
#include <thread>
using namespace std::chrono_literals;

template<typename T>
auto TimeIt(T callable){
    return [=](auto&&... args){
        auto start = std::chrono::system_clock::now();
        callable(args...);
        auto end = std::chrono::system_clock::now();
        std::chrono::duration<double> diff = end-start;
        std::cout << diff.count() << "s\n";
    };
}

void my_function(){
    // function code
    std::this_thread::sleep_for(0.5s);
}

auto my_function_2 = TimeIt(my_function); //you cannot reuse the name, though

int main(){
    my_function_2();
}

Wandbox

Upvotes: 2

Related Questions