c++ - 在模板函数包装器中处理 void 返回

标签 c++

我正在尝试编写一个用于日志记录和计时目的的函数包装器;跟随 this example ,到目前为止,我已经很好地掌握了如何做到这一点:

template <typename R, typename ...Args>
std::function<R(Args...)> logged(string name, std::function<R(Args...)> f)
{
    return [f,name](Args... args){

        LOG << name << " start" << NL;
        auto start = std::chrono::high_resolution_clock::now();

        R result = f(std::forward<Args>(args)...);

        auto end = std::chrono::high_resolution_clock::now();
        auto total = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
        LOG << "Elapsed: " << total << "us" << NL;

        return result;
    };
}

但是,这仅适用于具有非 void 返回类型的函数。虽然我可以轻松编写一个拷贝,用 void 替换“R”的所有实例(即获取并返回 std::function<void(Args...)> f ),但我宁愿尽可能避免重复。有什么方法可以处理 R 的情况吗?无效吗?

我尝试使用 type_traits::is_void 和分支逻辑来处理这个问题,但我总是会得到错误 missing template arguments before ( token if(!is_void(R)::value) .

我应该提一下,由于工作场所的限制,我正在使用 C++11。

最佳答案

您可以使用 RAII 来使用一个独特的功能:

template <typename F>
struct Finally {
    Finally(F f) : f(f) {}
    ~Finally() { f(); }

    Finally(const Finally&) = delete;
    Finally& operator=(const Finally&) = delete;

    F f;
};

// pre C++17
template <typename F>
Finally<F> make_finally(F f) {
    return {f};
}


template <typename R, typename ...Args>
std::function<R(Args...)> logged(string name, std::function<R(Args...)> f)
{
    return [f, name](Args... args) -> R {
        LOG << name << " start" << NL;
        auto start = std::chrono::high_resolution_clock::now();
        Finally finally([&](){ // C++17
        // auto&& finally = make_finally([&](){ // Pre-C++17
            auto end = std::chrono::high_resolution_clock::now();
            auto total = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
            LOG << "Elapsed: " << total << "us" << NL;
        });
        return f(std::forward<Args>(args)...);
    };
}

关于c++ - 在模板函数包装器中处理 void 返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51678936/

相关文章:

c++ - setupUi() 上的段错误

c++ - 调用另一个类中的一个类的 friend 成员失败

c++ - WMI 数据问题

c++ - 转换为 std::thread 状态调用私有(private)构造函数

c++ - 如何在完成工作后停止所有线程?

c++ - 有没有办法在 C++ 中隐式匹配嵌套模板类型?

c++ - Mac OSX 上的 c/c++ clang 链接错误 - webkitgtk

c++ - 楼主绘制的任务栏缩略图预览

c++ - MySQL C++ 不读取结果

c++ - boost program_options 开/关标志