c++ - 就地构建 std::function 目标

标签 c++ c++11 std-function

我所理解的 std::function 的典型用法

#include <iostream>
#include <functional>

using namespace std;

class C {
public: 
    C() { cout << "CREATING" << endl; }
    C(const C&) { cout << "COPY C "<< endl; };
    C(C&&) { cout << "MOVE C " << endl; };
    ~C() { cout << "DELETING"<< endl; }
    C& operator =(const C&) {
        cout << "COPY A " << endl; return *this;
    };
    C& operator =(C&&) {
        cout << "MOVE A" << endl; return *this;
    };
    void operator ()() const { cout << "CALLING" << endl; }
};

int main(int argc, char *argv[]) {
    function<void()> f = C();
    f();
    return 0;
}

产量如下输出

CREATING
MOVE C
DELETING
CALLING
DELETING

显然,临时对象是在堆栈上创建的,然后移入函数对象。如果未提供移动构造函数,则复制它。
是否有无需临时对象即可设置目标的标准方法?

最佳答案

function 由任何仿函数 F f 构造的方式由 §20.9.11.2.1 中的标准规定为(假设 f 是一个非空值,强调我的):

*this targets a copy of f initialized with std::move(f)

因此无法就地构造函数。这让您可以选择采取行动:

function<void()> f1 = C{};

或者传递一些围绕 C 的包装器,移动/复制成本更低,无论是您在其中进行外部管理:

C manage_me;
function<void()> f2 = std::ref(manage_me);

... 或分配的一个绑定(bind)到 operator():

function<void()> f3 = std::bind(&C::operator(), std::make_shared<C>());

如果 operator() 恰好重载,最后一个可能会引起一些麻烦,因为您必须将其转换为正确的类型,这是以前版本都没有的问题处理。

function<void()> f4 = std::bind(
                          static_cast<void(C::*)()>(&C::operator()),
                          std::make_shared<C>()
                          );

关于c++ - 就地构建 std::function 目标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27953336/

相关文章:

c++ - 如果输入错误,程序将进入无限循环

C++:将不可移动的仿函数传递给 std::function

c++ - std::function 作为模板参数

c++ - 尝试使用 std::functional 和 std::bind 在 C++ 中创建 C# 样式的事件访问修饰符

c++ - 试图让 C++ 程序循环回到代码中的另一点

c++ - 为什么我不能在 "if"语句中的整数前面放一个零

c++ - 为什么这段c++找不到结构成员 'filename'?

c++ - 丢失的一元 std::copy 的最佳实现

c++ - placement new 基于模板 sizeof()

c++ - 最简单最整洁的c++11 ScopeGuard