如何制作一个可以封装任何函数的函数封装器?

问题描述 投票:0回答:2
#include <iostream>
#include <string>

template<typename Func>
class FuncWrapper {
    Func func;
    std::string name;

public:

    FuncWrapper(Func func, std::string name) : func(func), name(std::move(name)) {}

    template<typename ...Args>
    auto operator()(Args ...args) {
        std::cout << "Entering " + name + '\n';
        auto ret = func(args...);
        std::cout << "Exiting " + name + "\n\n";
        return ret;
    }
};

template<typename Func>
auto makeFuncWrapper(Func func, std::string name) {
    return FuncWrapper<Func>(func, name);
}

int main() {

    auto helloWorld = []() { std::cout << "Hello World\n"; };
    auto addTwoNums = [](int a, int b) { std::cout << "Adding numbers...\n"; return a + b; };

    // makeFuncWrapper(helloWorld, "helloWorld")(); // error: 'void ret' has incomplete type.
    std::cout << makeFuncWrapper(addTwoNums, "addTwoNums")(4, 5) << '\n';

}

这个类 FuncWrapper 可以正常工作,并为传递的函数增加了额外的功能,直到传递的函数是一个返回了 void. 我得到一个错误的信息,即该类型的 ret 是不完整的。有没有其他方法可以让它在返回类型为 void? 我知道,我不能有一个 void 变量,但在这里, ret 是要在函数完成后返回的,不会用错。有什么办法或变通的办法让它工作吗?有什么更好的方法来实现一个可以封装任何函数的函数封装器吗?

c++ templates wrapper void
2个回答
1
投票

你可以使用Raii。

template<typename ...Args>
auto operator()(Args ...args) {
    struct EndScope {
        std::string& name;
        ~EndScope() { std::cout << "Exiting " + name + "\n\n"; }
    } endScope(name);

    std::cout << "Entering " + name + '\n';
    return func(args...);
}

你可以进一步用 std::uncaught_exceptions

请看 raii-way to get-errors-that-are-caught-during-destroying(破坏过程中捕获的错误)。

© www.soinside.com 2019 - 2024. All rights reserved.