【问题标题】:How to capture a type of return value of a function returning a lambda?如何捕获返回 lambda 的函数的返回值类型?
【发布时间】:2019-04-27 08:44:50
【问题描述】:

鉴于此代码:

template <class Func> class ScopeGuard
{
public:
    /** @param func function object to be executed in dtor
    */
    explicit ScopeGuard( Func && func ) : m_func( std::move(func) ) {}

    ~ScopeGuard()
    {
        if (m_bDismissed)
            return;
        m_func();
    }

    /** Dismisses the scope guard, i.e. the function won't
        be executed.
    */
    void dismiss() { m_bDismissed = true; }

private:
    // noncopyable until we have good reasons...
    ScopeGuard(const ScopeGuard&) = delete;
    ScopeGuard& operator=(const ScopeGuard&) = delete;

    Func m_func;
    bool m_bDismissed = false;
};

// Get functor for cleanup to use in FlagRestorationGuard
auto GetFlagRestorationGuard(bool& i_flagRef)
{
    return [&i_flagRef, resetVal = i_flagRef] { i_flagRef = resetVal; };
}

class FlagRestorationGuard : public ScopeGuard<decltype(GetFlagRestorationGuard(*(new bool)))>
{
public:
    FlagRestorationGuard( bool& i_flagRef, bool i_temporaryValue )
        : ScopeGuard(GetFlagRestorationGuard(i_flagRef))
    {
        i_flagRef = i_temporaryValue;
    }
};

使用 Apple Clang 为 GetFlagRestorationGuard(*(new bool)) 构建时出现以下错误:

错误:具有副作用的表达式在未评估的上下文中无效 [-Werror,-Wunevaluated-expression]

请注意,此代码可与 MSVC 2017 一起构建并正常工作。 当然,可以全部重写以使用带有operator()() 的结构而不是 lambda 和返回它的函数,但我想知道是否有像这样使用 lambda 的好方法?

Reference 为实际代码:

Reference构建失败:

【问题讨论】:

    标签: c++ templates lambda


    【解决方案1】:

    std::declvalbool 的左值引用一起使用:

    class FlagRestorationGuard :
        public ScopeGuard<decltype(GetFlagRestorationGuard(std::declval<bool&>()))>
    {
        ...
    };
    

    【讨论】:

      【解决方案2】:

      这是您看到的警告;不是错误。它警告您new bool(分配内存)的副作用不会发生,因为它处于未评估的上下文中。

      要消除警告,不要在 decltype 表达式中使用 *(new bool) 作为占位符参数,而是使用 std::declval&lt;bool&amp;&gt;

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-21
        • 1970-01-01
        • 2018-12-15
        • 2016-04-23
        • 1970-01-01
        • 1970-01-01
        • 2021-05-28
        • 2020-08-06
        相关资源
        最近更新 更多