6
#include <iostream>
using namespace std;

#include <functional>

        template <class F>
        class ScopeExitFunction
        {
        public:
            ScopeExitFunction(F& func) throw() :
                m_func(func)
            {
            }

            ScopeExitFunction(F&& func) throw() :
                m_func(std::move<F>(func))
            {
            }

            ScopeExitFunction(ScopeExitFunction&& other) throw() :
                m_func(std::move(other.m_func))
            {
             //  other.m_func = []{};
            }

            ~ScopeExitFunction() throw()
            {
                m_func();
            }

        private:
            F m_func;
        };

int main() {
    {
        std::function<void()> lambda = [] { cout << "called" << endl; };
        ScopeExitFunction<decltype(lambda)> f(lambda);
        ScopeExitFunction<decltype(lambda)> f2(std::move(f));
    }
    return 0;
}

この行のコメントを外さない// other.m_func = []{}; と、プログラムは次の出力を生成します。

プログラムを実行しています.... $demo called terminate called after throwing an instance of 'std::bad_function_call' what(): bad_function_call

移動時に std::function が内部関数をリセットしないのは正常ですか?

4

2 に答える 2

12

C++11 20.8.11.2.1/6 [func.wrap.func.con] によると、既存のオブジェクトからムーブ構築を行うとstd::function、元のオブジェクトは「指定されていない値を持つ有効な状態」のままになります。なので、基本的に何も考えないでください。元の関数オブジェクトを使用しないか、まだ必要な場合はそこから移動しないでください。

于 2013-11-15T10:05:07.780 に答える