如何捕获返回lambda的函数的返回值类型?

时间:2019-04-27 08:44:50

标签: c++ templates lambda

给出以下代码:

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;
    }
};

我在使用GetFlagRestorationGuard(*(new bool))的Apple Clang时遇到以下错误:

  

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

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

Reference(实际代码):

Reference建立失败:

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:2)

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

要摆脱警告,请使用*(new bool)。不要在您的decltype表达式中使用std::declval<bool&>作为占位符。