Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 包裹c++;11 std::函数在另一个std::函数中?_C++_C++11_Boost_Boost Signals2 - Fatal编程技术网

C++ 包裹c++;11 std::函数在另一个std::函数中?

C++ 包裹c++;11 std::函数在另一个std::函数中?,c++,c++11,boost,boost-signals2,C++,C++11,Boost,Boost Signals2,我想将std::bind()或lambda的结果包装到一个helper函数中,该函数跟踪函数调用的执行时间。我想要一个通用的解决方案,它可以处理任意数量的参数(和类方法),并且与c++11兼容 我的目的是获取包装好的函数并将其传递给boost::signals2::signal,因此结果函数对象的签名需要与原始函数相同 我基本上在寻找一些神奇的类或函数Wrapper,其工作原理如下: std::function<void(int)> f = [](int x) { std::

我想将std::bind()或lambda的结果包装到一个helper函数中,该函数跟踪函数调用的执行时间。我想要一个通用的解决方案,它可以处理任意数量的参数(和类方法),并且与c++11兼容

我的目的是获取包装好的函数并将其传递给boost::signals2::signal,因此结果函数对象的签名需要与原始函数相同

我基本上在寻找一些神奇的类或函数
Wrapper
,其工作原理如下:

std::function<void(int)> f = [](int x) {
    std::cerr << x << std::endl;
};

boost::signals2::signal<void(int)> x_signal;
x_signal.connect(Wrapper<void(int)>(f));
x_signal(42);
std::函数f=[](int x){

我相信你想做的事情可以用可变模板来解决

基本上,您可以将参数列表从外部std::函数“转发”到内部

编辑:

下面,我添加了一个使用可变模板概念的最小工作示例
,使用内部lambda函数的指定参数将lambda函数包装到另一个
std::function
对象中。这是通过将要测量的函数作为参数传递给模板函数
measureTimeWrapper
。它返回一个与传入函数具有相同签名的函数(假设您在
measureTimeWrapper
的模板参数中正确定义了lambda的参数列表)

测量运行时间的函数只是坐在这里,等待由其参数定义的毫秒数。除此之外,它根本不关心时间测量。这是由包装器函数完成的

请注意,内部函数的返回值以这种方式丢失;如果要保留它,可能需要更改返回值的方式(可能作为结构,包含测量的时间和实际返回值)

请记住至少使用
-std=c++11
编译代码

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


template<typename T, typename... Args>
std::function<double(Args...)> measureTimeWrapper(std::function<T> fncFunctionToMeasure) {
  return [fncFunctionToMeasure](Args... args) -> double {
    auto tsStart = std::chrono::steady_clock::now();
    fncFunctionToMeasure(args...);
    auto tsEnd = std::chrono::steady_clock::now();

    std::chrono::duration<double> durTimeTaken = tsEnd - tsStart;

    return durTimeTaken.count();
  };
}

int main(int argc, char** argv) {
  std::function<double(int)> fncMeasured = measureTimeWrapper<void(int), int>([](int nParameter) {
      std::cout << "Process function running" << std::endl;

      std::chrono::milliseconds tsTime(nParameter); // Milliseconds
      std::this_thread::sleep_for(tsTime);
    });

  std::cout << "Time taken: " << fncMeasured(500) << " sec" << std::endl;

  return EXIT_SUCCESS;
}
#包括
#包括
#包括
#包括
#包括
模板
std::function measureTimeWrapper(std::function fncFunctionToMeasure){
返回[fncFunctionToMeasure](参数…参数)->双精度{
自动启动=标准::计时::稳定时钟::现在();
fncFunctionToMeasure(参数…);
auto-tsEnd=std::chrono::stational_clock::now();
std::chrono::duration durtimetaked=tsEnd-tsStart;
返回durtimetaked.count();
};
}
int main(int argc,字符**argv){
std::function fncMeasured=measureTimeWrapper([](int-n参数){
std::cout
#包括
#包括
模板
std::函数包装器(std::function func)
{
返回[func](自动…参数)
{

如果是关于性能,我强烈建议不要双重包装函数

您可以不使用这些:

template <typename Caption, typename F>
auto timed(Caption const& task, F&& f) {
    return [f=std::forward<F>(f), task](auto&&... args) {
        using namespace std::chrono;

        struct measure {
            high_resolution_clock::time_point start;
            Caption const& task;
            ~measure() { std::cout << " -- (" << task << " completed in " << duration_cast<microseconds>(high_resolution_clock::now() - start).count() << "µs)\n"; }
        } timing { high_resolution_clock::now(), task };

        return f(std::forward<decltype(args)>(args)...);
    };
}
更新:c++11版本

#include <chrono>
#include <iostream>

template <typename Caption, typename F>
auto timed(Caption const& task, F&& f) {
    return [f=std::forward<F>(f), task](auto&&... args) {
        using namespace std::chrono;

        struct measure {
            high_resolution_clock::time_point start;
            Caption const& task;
            ~measure() { std::cout << " -- (" << task << " completed in " << duration_cast<microseconds>(high_resolution_clock::now() - start).count() << "µs)\n"; }
        } timing { high_resolution_clock::now(), task };

        return f(std::forward<decltype(args)>(args)...);
    };
}

#include <thread>

int main() {
    using namespace std;
    auto f = timed("IO", [] { cout << "hello world\n"; return 42; });
    auto g = timed("Sleep", [](int i) { this_thread::sleep_for(chrono::seconds(i)); });

    g(1);
    f();
    g(2);

    std::function<int()> f_wrapped = f;
    return f_wrapped();
}
#include <chrono>
#include <iostream>

namespace detail {

    template <typename F>
    struct timed_impl {
        std::string _caption;
        F _f;

        timed_impl(std::string const& task, F f) 
            : _caption(task), _f(std::move(f)) { }

        template <typename... Args>
        auto operator()(Args&&... args) const -> decltype(_f(std::forward<Args>(args)...))
        {
            using namespace std::chrono;

            struct measure {
                high_resolution_clock::time_point start;
                std::string const& task;
                ~measure() { std::cout << " -- (" << task << " completed in " << duration_cast<microseconds>(high_resolution_clock::now() - start).count() << "µs)\n"; }
            } timing { high_resolution_clock::now(), _caption };

            return _f(std::forward<decltype(args)>(args)...);
        }
    };
}

template <typename F>
detail::timed_impl<F> timed(std::string const& task, F&& f) {
    return { task, std::forward<F>(f) };
}

#include <thread>

int main() {
    using namespace std;
    auto f = timed("IO", [] { cout << "hello world\n"; return 42; });
    auto g = timed("Sleep", [](int i) { this_thread::sleep_for(chrono::seconds(i)); });

    g(1);
    f();
    g(2);

    std::function<int()> f_wrapped = f;
    return f_wrapped();
}
#包括
#包括
名称空间详细信息{
模板
结构定时\u impl{
std::string\u标题;
F(u)F,;
定时执行(标准::字符串常量和任务,F)
:_标题(任务),_f(标准::移动(f)){}
模板
自动运算符()
{
使用名称空间std::chrono;
结构度量{
高分辨率时钟:时间点开始;
std::字符串常量和任务;

~measure(){std::cout您想如何处理执行时间?直接将其打印到标准输出?您可以这样做,并将大部分艰苦的工作委托给std::function。使用C++11和boost.signals2:@melak47 ah-实际上没有查看您的示例。我回答中的RAII技巧避免了
void
返回类型!的特殊情况SO上不需要太多的答案。而且cplusplus.com也没有被广泛视为主要资源。@sehe我明白了这一点,并添加了一个工作代码示例和更多的解释。谢谢你的提示。不过,我不明白为什么cplusplus.com不应该是一个有效的参考。还有其他一些地方,我看到了,谢谢。不过,它从来没有任何问题。这是我的建议它非常优秀,可以在c++11中工作,但不满足我的boost::signals2要求。不过,如果您稍微更改它(返回void而不是time double)然后它工作得很好。不幸的是,这并没有推广到任何返回类型,但对于信号我无论如何都不关心。谢谢!事实上,我更喜欢你的,因为你在
timed
中不需要模板参数。我会注意到,以后,
std::forward
decltype
是一个很好的组合使用可变模板。我忘了在帖子中提到我使用的是c++11。这是一个很好的解决方案,但返回auto需要c++14。如果我将您的live demo更改为std=c++11,它将不再编译。@moof2k没问题。然后会稍微详细一些。稍后将发布tonight@moof2k好了,在晚饭前匆匆吃完:这是最令人敬畏的我有一个答案,但遗憾的是,我所处的平台还不支持c++14。谢谢!
 -- (Sleep completed in 1000188µs)
hello world
 -- (IO completed in 2µs)
 -- (Sleep completed in 2000126µs)
hello world
 -- (IO completed in 1µs)
exitcode: 42
#include <chrono>
#include <iostream>

namespace detail {

    template <typename F>
    struct timed_impl {
        std::string _caption;
        F _f;

        timed_impl(std::string const& task, F f) 
            : _caption(task), _f(std::move(f)) { }

        template <typename... Args>
        auto operator()(Args&&... args) const -> decltype(_f(std::forward<Args>(args)...))
        {
            using namespace std::chrono;

            struct measure {
                high_resolution_clock::time_point start;
                std::string const& task;
                ~measure() { std::cout << " -- (" << task << " completed in " << duration_cast<microseconds>(high_resolution_clock::now() - start).count() << "µs)\n"; }
            } timing { high_resolution_clock::now(), _caption };

            return _f(std::forward<decltype(args)>(args)...);
        }
    };
}

template <typename F>
detail::timed_impl<F> timed(std::string const& task, F&& f) {
    return { task, std::forward<F>(f) };
}

#include <thread>

int main() {
    using namespace std;
    auto f = timed("IO", [] { cout << "hello world\n"; return 42; });
    auto g = timed("Sleep", [](int i) { this_thread::sleep_for(chrono::seconds(i)); });

    g(1);
    f();
    g(2);

    std::function<int()> f_wrapped = f;
    return f_wrapped();
}