【问题标题】:does std::function reset its internal function after being movedstd::function 移动后是否重置其内部功能
【发布时间】:2013-11-15 10:02:50
【问题描述】:
#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 调用 terminate 之后调用 抛出 'std::bad_function_call' what() 的实例: bad_function_call

std::function 移动时不重置其内部函数是否正常?

【问题讨论】:

  • std::forward&lt;F&gt;(func),在来自F&amp;&amp; 的构造函数中只是一种尴尬的说法std::move(func)
  • msvc2013 下有一个错误,这就是我使用 std::forward 的原因
  • msvc2010 的勘误错误

标签: c++ c++11


【解决方案1】:

根据 C++11 20.8.11.2.1/6 [func.wrap.func.con],从现有 std::function 对象进行移动构造会使原始对象“处于具有未指定值的有效状态” .所以基本上不要假设任何事情。只是不要使用原来的函数对象,或者如果你仍然需要它就不要离开它。

【讨论】:

  • 或者写你自己的::std::functionlookalike。
  • @user1095108:为什么...?
  • 也许他希望::std::function 提供一些不存在的东西。
  • 你当然可以检查被移动的对象是否仍然有一个目标,但是你不知道绑定的成员是否处于任何合理的状态,所以你真的无能为力- 从对象。因此,如果您仍然想使用它,请不要移动。充其量你可能想检查是否有人有条件地从你通过左值引用传递的对象获得所有权;在这种情况下,您可以指示调用者重置函数以表明所有权已被占用。
  • @KerrekSB “为什么……?” - 了解为什么不需要写一个!
【解决方案2】:

std::function 移动时不重置其内部函数是否正常?

相反,在您的情况下,它确实重置了内部函数,这意味着内部句柄设置为零,std::function 不再是真正的函数。自从那件事发生后,对operator() 的调用就不顺利了。

【讨论】:

    猜你喜欢
    • 2012-04-18
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多