繁体   English   中英

如何使用自定义分配器创建 std::function?

[英]How can I create a std::function with a custom allocator?

为了保存一些代码,假设我有一个名为MyAlloc的自定义分配器,我已成功将其与std::vector<int> ,如下所示:

std::vector<int,MyAlloc<int>> vec;

现在我想使用自定义分配器将 lambda 保存在 std::function 中,我该怎么做?

我失败的尝试:

int i[100];
std::function<void(int)> f(MyAlloc<void/*what to put here?*/>{},[i](int in){
    //...
});

更新: std::function 中的分配器已被弃用

根据标准,你需要给一个标签类型作为第一个参数来表明你要使用自定义分配器:

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::function 重载分配器时努力使语法正确。

如果读者不清楚,您需要根据 Casey 的评论声明一个分配器类。 尽管如果您阅读所有回复,这是相当明显的,但不清楚的是这些分配器传递给对象的方式与我之前使用的大多数 STL 分配器不同,它们采用分配器类型(不是实例) 作为类型规范的一部分。

对于 std::function实例化分配器提供给 std::function 对象的构造函数,这就是 ComicSansMS 上面显示的内容。

为了使用成员函数而不是本示例中显示的 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);

希望这对人们有所帮助,我花了比我想承认的时间更长的时间才能让它工作,而且就我使用这个网站而言,我想如果除了我自己之外没有其他人,我会在这里发表评论. :)

给比我更聪明的人的最后两个问题:

问:有没有办法将分配器作为类型的一部分包含在内?

问:有没有办法在没有对象实例的情况下使用成员函数?

为了更新这一点,如果您决定将这些 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 ); 

    ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM