我应该复制一个 std::function 还是我可以总是引用它?

2021-12-23 00:00:00 lambda c++ std-function

在我的 C++ 应用程序(使用 Visual Studio 2010)中,我需要存储一个 std::function,如下所示:

In my C++ application (using Visual Studio 2010), I need to store an std::function, like this:

class MyClass
   {
   public:
      typedef std::function<int(int)> MyFunction;
      MyClass (Myfunction &myFunction);
   private:
      MyFunction m_myFunction;    // Should I use this one?
      MyFunction &m_myFunction;   // Or should I use this one?
   };

如您所见,我在构造函数中添加了函数参数作为引用.

As you can see, I added the function argument as a reference in the constructor.

但是,在我的类中存储函数的最佳方式是什么?

But, what is the best way to store the function in my class?

  • 由于 std::function 只是一个函数指针并且保证函数的可执行代码"保留在内存中,我可以将函数存储为引用吗?
  • 如果传递了 lambda 并且调用者返回,我是否必须复制一份?

我的直觉是存储引用(甚至是常量引用)是安全的.我希望编译器在编译时为 lambda 生成代码,并在应用程序运行时将此可执行代码保存在虚拟"内存中.因此,永远不会删除"可执行代码,我可以安全地存储对它的引用.但这真的是真的吗?

My gut feeling says that it's safe to store a reference (even a const-reference). I expect the compiler to generate code for the lambda at compile time, and keep this executable code in 'virtual' memory while the application is running. Therefore the executable code is never 'deleted' and I can safely store a reference to it. But is this really true?

推荐答案

我可以将函数存储为引用,因为 std::function 只是一个函数指针并且函数的可执行代码"保证保留在内存中?

Can I store the function as a reference since std::function is just a function-pointer and the 'executable code' of the function is guaranteed to stay in memory?

std::function 不仅仅是一个函数指针.它是任意可调用对象的包装器,并管理用于存储该对象的内存.与任何其他类型一样,仅当您有其他方法来保证引用的对象在使用该引用时仍然有效时,才可以安全地存储引用.

std::function is very much not just a function pointer. It's a wrapper around an arbitrary callable object, and manages the memory used to store that object. As with any other type, it's safe to store a reference only if you have some other way to guarantee that the referred object is still valid whenever that reference is used.

除非你有一个很好的理由来存储一个引用,并且有一种方法来保证它保持有效,否则按值存储它.

Unless you have a good reason for storing a reference, and a way to guarantee that it remains valid, store it by value.

const 引用传递给构造函数是安全的,并且可能比传递值更有效.传递非const 引用是个坏主意,因为它会阻止你传递一个临时的,所以用户不能直接传递一个lambda,bind 的结果,或除 std::function 本身之外的任何其他可调用对象.

Passing by const reference to the constructor is safe, and probably more efficient than passing a value. Passing by non-const reference is a bad idea, since it prevents you from passing a temporary, so the user can't directly pass a lambda, the result of bind, or any other callable object except std::function<int(int)> itself.

相关文章