c++ - 如果 `f` 具有非空返回类型,则返回 `f` 的结果——如何重构此模式?

标签 c++ refactoring metaprogramming c++14 return-type

我有一个 step(f) 函数:

  1. 在调用 f 之前执行一些代码。

  2. 调用 f()

  3. 调用f后执行一些代码。

  4. 返回f的结果值如果f不返回void

由于上述第四点,实现 step 的一小段代码让我更加困扰:

template <typename TF>
auto step(TF&& f)
{   
    // Execute some actions before `f`. 
    do_something();

    using f_return_type = decltype(f());
    return static_if(std::is_same<f_return_type, void>{})
        .then([](auto&& xf) mutable
            {
                // Do not return anything if `xf` returns void.
                xf();

                // Execute some actions after `f`.
                do_something_after_f();
            })
        .else_([](auto&& xf) mutable
            {
                auto result = xf();

                // Execute some actions after `f`.
                do_something_after_f();

                return result;
            })(std::forward<TF>(f));
}

(注意重复调用 fdo_something_after_f。)

我必须使用某种条件编译时(模板特化或static_if,如示例所示)根据f<进行分支 的返回类型。

理想情况下,我希望这样可以编译:

template <typename TF>
auto step(TF&& f)
{   
    // Execute some actions before `f`. 
    do_something();

    decltype(auto) eventual_result = f();

    // Execute some actions after `f`.
    do_something_after_f();

    return result;
}

但不是,因为eventual_result可以是void,这是一个不完整的类型。

是否有任何方法可以重构此代码以避免重复调用 f()do_something_after_f()

最佳答案

您可以通过将返回语句放入局部变量的析构函数中,让 do_something_after_f() 在返回语句之后运行。

struct Cleanup {
    ~Cleanup() { do_something_after_f(); }
} cleanup;
return f(); // it's legal to return a void expression in C++

关于c++ - 如果 `f` 具有非空返回类型,则返回 `f` 的结果——如何重构此模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37489952/

相关文章:

C++ deque迭代到倒数第二个元素

design-patterns - 避免将 boolean 标志作为属性

Java动态方法创建

java - 在 Eclipse JDT 中放置变量 1 上下文

c++ - 在编译时生成唯一编号

ruby - `send` 替代 Ruby 中的 lambda

C++和互联网程序

c++ - 将 C++ 模板类型限制为特定的变量大小

c++ - 有没有更好的办法? While 循环并继续

c# - 如何重构测试应用?