在C++

发布于 2025-01-30 14:51:39 字数 1635 浏览 1 评论 0原文

上一篇文章,在c 中以优雅的方式进行时间安排使用包装器功能进行分析的整洁方法。我正在尝试使用其中一位参考器来介绍我的类功能。

#include <cmath>
#include <string>
#include <chrono>
#include <algorithm>
#include <iostream>

template<typename Duration = std::chrono::microseconds,
         typename F,
         typename ... Args>
typename Duration::rep profile(F&& fun,  Args&&... args) {
  const auto beg = std::chrono::high_resolution_clock::now();
  std::forward<F>(fun)(std::forward<Args>(args)...);
  const auto end = std::chrono::high_resolution_clock::now();
  return std::chrono::duration_cast<Duration>(end - beg).count();
}

Profiler为正常功能工作,但我正在努力将类功能传递给Profiler。

#include "Profiler.h"

int main()
{
    Config projConfig = Config(projConfigDir);
    std::string imagePath = projConfig.GetTIFF();
    
    ImageVector images_vec = Image::LoadImagesVec(imagePath);
    Detector detector = Detector(&projConfig);

    auto time = profile<std::chrono::seconds>(&Detector::DetectImages, detector, images_vec);
    //detector.DetectImages(images_vec); // if ran without profiler
    std::string _detectTime("DetectImages time elapsed: " + std::to_string(time));
    Logger::Info(_detectTime.c_str());
}

我无法编译代码。我收到以下错误消息。

term does not evaluate to a function taking 2 arguments

因为我无法将指针传递给有界函数到探测器,所以我尝试通过函数传递该函数来调用函数和函数的参数(不确定这是否是正确的方式)。但是我怀疑未实施参考器来处理类方法。如果是这样,我应该如何修改Profiler,以便它可以接受类功能?

A previous post, Timing in an elegant way in C, showed a neat method for profiling using a wrapper function. I am trying to use one of the profiler to profile my class functions.

#include <cmath>
#include <string>
#include <chrono>
#include <algorithm>
#include <iostream>

template<typename Duration = std::chrono::microseconds,
         typename F,
         typename ... Args>
typename Duration::rep profile(F&& fun,  Args&&... args) {
  const auto beg = std::chrono::high_resolution_clock::now();
  std::forward<F>(fun)(std::forward<Args>(args)...);
  const auto end = std::chrono::high_resolution_clock::now();
  return std::chrono::duration_cast<Duration>(end - beg).count();
}

The profiler works for a normal function, but I am struggling to pass a class function to the profiler.

#include "Profiler.h"

int main()
{
    Config projConfig = Config(projConfigDir);
    std::string imagePath = projConfig.GetTIFF();
    
    ImageVector images_vec = Image::LoadImagesVec(imagePath);
    Detector detector = Detector(&projConfig);

    auto time = profile<std::chrono::seconds>(&Detector::DetectImages, detector, images_vec);
    //detector.DetectImages(images_vec); // if ran without profiler
    std::string _detectTime("DetectImages time elapsed: " + std::to_string(time));
    Logger::Info(_detectTime.c_str());
}

I am unable to compile the code. I got the following error message.

term does not evaluate to a function taking 2 arguments

Because I cannot pass pointer to a bounded function to the profiler, I tried passing in the function, the object instance to call the function and the function's arguments (not sure if this is the correct way). But I suspect that the profiler is not implemented to handle class methods. If so, how should I modify the profiler so that it can accept class functions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

红衣飘飘貌似仙 2025-02-06 14:51:39

您可以使用 std :: bind << < /strong> 创建一个可可的对象,用于在类对象上调用类方法。

然后,您可以将此可召唤传递给您的配置文件函数,因为您将通过任何功能/lambda。
请注意,使用std :: bind支持还修复一个或多个方法参数。
使用 std ::占位符::占位符 (AS AS您可以在下面看到)仅在调用贝丁可召唤对象时才指定它们。

请参见下面的示例:

#include <chrono>
#include <iostream>
#include <functional>
#include <thread>
#include <string>

template<typename Duration = std::chrono::microseconds,
         typename F,
         typename ... Args>
    typename Duration::rep profile(F&& fun, Args&&... args) 
{
    const auto beg = std::chrono::high_resolution_clock::now();
    std::forward<F>(fun)(std::forward<Args>(args)...);
    const auto end = std::chrono::high_resolution_clock::now();
    return std::chrono::duration_cast<Duration>(end - beg).count();
}

struct MyClass
{
    void Run(std::string const & s, double d)
    {
        std::cout << "My id: " << id << ",  MyClass::Run(" << s << ", " << d << ")" << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
    int id{ 333 };
};

int main()
{
    MyClass c;

    // Run without profiling:
    c.Run("without", 2.3);

    // Run  with profiling:
    auto f = std::bind(&MyClass::Run, &c, std::placeholders::_1, std::placeholders::_2);
    auto time = profile<std::chrono::milliseconds>(f, "with", 23);
    std::cout << "time: " << time << std::endl;
    return 0;
}

输出:

My id: 333,  MyClass::Run(without, 2.3)
My id: 333,  MyClass::Run(with, 23)
time: 109

You can use std::bind to create a callable object for invoking a class method on a class object.

Then you can pass this callable to your profile function as you would pass any function/lambda.
Note that using std::bind supports also fixing one or more of the method parameters.
Using std::placeholders (as you can see below) allows to specify them only when invoking the binded callable object.

See the example below:

#include <chrono>
#include <iostream>
#include <functional>
#include <thread>
#include <string>

template<typename Duration = std::chrono::microseconds,
         typename F,
         typename ... Args>
    typename Duration::rep profile(F&& fun, Args&&... args) 
{
    const auto beg = std::chrono::high_resolution_clock::now();
    std::forward<F>(fun)(std::forward<Args>(args)...);
    const auto end = std::chrono::high_resolution_clock::now();
    return std::chrono::duration_cast<Duration>(end - beg).count();
}

struct MyClass
{
    void Run(std::string const & s, double d)
    {
        std::cout << "My id: " << id << ",  MyClass::Run(" << s << ", " << d << ")" << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
    int id{ 333 };
};

int main()
{
    MyClass c;

    // Run without profiling:
    c.Run("without", 2.3);

    // Run  with profiling:
    auto f = std::bind(&MyClass::Run, &c, std::placeholders::_1, std::placeholders::_2);
    auto time = profile<std::chrono::milliseconds>(f, "with", 23);
    std::cout << "time: " << time << std::endl;
    return 0;
}

Output:

My id: 333,  MyClass::Run(without, 2.3)
My id: 333,  MyClass::Run(with, 23)
time: 109
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文