如何使用自定义分配器创建std::函数
How can I create a std::function with a custom allocator?
为了保存一些代码,假设我有一个名为MyAlloc
的自定义分配器,我已经成功地将其与std::vector<int>
一起使用,如下所示:
std::vector<int,MyAlloc<int>> vec;
现在我想使用自定义分配器将lambda保存在std::函数中,该怎么做?
我失败的尝试:
int i[100];
std::function<void(int)> f(MyAlloc<void/*what to put here?*/>{},[i](int in){
//...
});
更新:std::函数中的分配器已弃用
根据标准,您需要提供一个标记类型作为第一个参数,以指示您想要使用自定义分配器:
std::function<void(int)> f(std::allocator_arg, MyAlloc<char>{}, [i](int in){
//...
});
正如@Casey和@Potatoswatter在评论中指出的那样,给分配器的模板参数类型无关紧要,只要它是对象类型即可。所以char
在这里是好的。
C++17的更新:事实证明,对std::function
的分配器支持存在许多基本问题,这些问题导致它在C++17中被弃用。如果你仍然坚持使用它,在这样做之前一定要仔细检查你的实现。GCC的标准库从未实现过这些函数,但即使你的标准库实现了,它也可能不会按照你期望的方式运行。
我意识到这个问题得到了正确的回答,但即使在阅读了这篇文章和回复之后,我也有点难以获得正确的语法,试图为VS2012中在X64、PS4和Xbox One上交叉编译的std::函数重载分配器。
如果读者不清楚,您需要根据Casey的注释声明一个分配器类。尽管如果你阅读了所有的回复,这一点很明显,但不清楚的是这些分配器传递给对象的方式,这与我以前使用的大多数STL分配器不同,它们将分配器类型(而不是实例)作为类型规范的一部分。
对于std::函数,会向std::function对象的构造函数提供一个实例化的分配器,这就是ComicansMS上面显示的内容。
对于将其与成员函数(而不是本示例中显示的lambda代码)一起使用,它会变得有点棘手:
#include <functional>
MyAllocType g_myAlloc; // declared somewhere and globally instantiated to persist
// sample of a member function that takes an int parameter
class MyClassType
{
public:
void TestFunction( int param )
{
}
};
MyClassType MyClass; // instantiated object
// example without allocator
// note the pointer to the class type that must precede function parameters since
// we are using a method. Also std::mem_fn is require to compile in VS2012 :/
std::function<void(MyClassType*, int)> f( std::mem_fn( &MyClassType::TestFunction ) );
// usage of function needs an instantiated object (perhaps there is a way around this?)
f( &MyClass, 10 );
// example with allocator
std::function<void(MyClassType*, int)> f(std::allocator_arg, g_myAlloc, std::mem_fn( &MyClassType::TestFunction ) );
// usage of function is the same as above and needs an instantiated object
f( &MyClass, 10 );
//or a non member function, which is much cleaner looking
void NonMemberFunction( int param )
{
}
std::function<void(int)> f(std::allocator_arg, g_myAlloc, NonMemberFunction);
希望这能帮助到人们,我花了比我想承认的更长的时间才让它发挥作用,尽管我使用了这个网站,但我想如果除了我自己,没有人知道如何使用它,我会在这里留下评论。:)
最后两个问题给那些比我聪明的人:
Q: 有没有一种方法可以将分配器作为类型的一部分?
Q: 有没有一种方法可以在没有对象实例的情况下使用成员函数?
为了更新这一点,如果您决定将其中一个std::function对象作为参数传递给其他函数,我发现我需要使用std::function::assign,否则赋值会导致浅拷贝。如果您试图将其传递给一个生命周期比原始对象更长的对象,这可能会成为一个问题。
示例:
std::function<void(MyClassType*, int)> f(std::allocator_arg, g_myAlloc, std::mem_fn( &MyClassType::TestFunction ) );
void FunctionTakeParam( std::function<void(MyClassType*, int)> &FunctionIn )
{
// this results in a reallocation using your allocator
std::function<void(MyClassType*, int)> MyLocalFunction.assign( std::allocator_arg, g_myAlloc, FunctionIn );
// the below results in a shallow copy which will likely cause bad things
//std::function<void(MyClassType*, int)> MyLocalFunction( std::allocator_arg, g_myAlloc, FunctionIn );
...
}
- 使用std::函数映射对象方法
- 可组合的lambda/std::函数与std::可选
- 当使用透明的std函数对象时,我们还需要写空的尖括号吗
- std::函数常量正确性未遵循
- 具有变量Number of Arguments的std::函数的矢量
- 从类型std::函数传递变量失败,尽管调用方期望的类型完全相同
- 如何调用存储在指向"std::函数"的指针中的 lambda?
- C++ STD 函数运算符:有没有一种方法可以通过函数将一个向量映射到另一个向量上?
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 如何将类 1 的 std::函数绑定到类 2 的函数?
- 如何制作可以接受任何类型的参数的 std::函数和 lambda
- 如何将 STL 队列推送函数绑定到 std::函数?
- std::函数不起作用,但普通的旧函数指针可以 - 为什么?
- 获取 std::函数以推断按引用传递/按值传递
- std::bind 和 std::函数术语不值为接受 0 个参数?
- 从其存储的回调中删除 std::函数是否安全
- 创建 std::函数,它返回具有函数成员值的变量.分段错误
- 创建一个带有 lambda 的 std::函数,而不知道函数的参数
- std::函数的解释
- 在调用过程中删除 std::函数