c++ c++11 allocator

c++ - ¿Cómo puedo crear una función std:: con un asignador personalizado?



c++11 allocator (2)

De acuerdo con el estándar, debe proporcionar un tipo de etiqueta como primer argumento para indicar que desea usar un asignador personalizado:

std::function<void(int)> f(std::allocator_arg, MyAlloc<char>{}, [i](int in){ //... });

Como lo señalaron @Casey y @Potatoswatter en los comentarios, el tipo de argumento de plantilla dado al asignador no importa, siempre que sea un tipo de objeto. Así que la char está bien aquí.

Actualización para C ++ 17 : Resulta que el soporte del asignador para la std::function tiene una serie de problemas fundamentales, que hacen que se desapruebe en C ++ 17 . Si aún así insiste en usarlo, asegúrese de verificar cuidadosamente su implementación antes de hacerlo. La biblioteca estándar de GCC nunca implementó esas funciones, pero incluso si la biblioteca estándar lo hace, es posible que no se comporte de la forma esperada.

Para guardar algo de código, digamos que tengo un asignador personalizado llamado MyAlloc que he usado con éxito con un std::vector<int> siguiente manera:

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

ahora quiero guardar un lambda en una función std :: utilizando el asignador personalizado, ¿cómo lo hago?

Mi intento fallido:

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

Actualización: los asignadores en la función std :: han sido depricated


Me doy cuenta de que esto se respondió correctamente, pero incluso después de leer este artículo y las respuestas, me costó un poco obtener la sintaxis correcta al intentar sobrecargar un asignador para std :: function que se compila en X64, PS4 y Xbox One en VS2012.

Si el lector no lo tiene claro, deberá declarar una clase de asignador según el comentario de Casey. Aunque esto es bastante obvio si leyó todas las respuestas, lo que no quedó claro fue la forma en que estos asignadores se pasan al objeto, que no es como la mayoría de los asignadores STL que he usado antes, que toman un tipo de asignador (no una instancia). ) como parte de la especificación de tipo.

Para std :: function se suministra un asignador de instancias al constructor de su objeto std :: function, que es lo que ComicSansMS está mostrando arriba.

Para usar esto con una función miembro en lugar del código lambda que se muestra en este ejemplo, se vuelve un poco complicado:

#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);

Espero que esto ayude a la gente, me tomó más tiempo del que me gustaría admitir para que esto funcione, y por mucho que use este sitio, pensé en dejar un comentario aquí si no fuera por mí mismo sobre cómo usarlo. . :)

2 preguntas finales para aquellos que son más inteligentes que yo:

P: ¿Hay alguna manera de incluir el asignador como parte del tipo?

P: ¿Hay una manera de usar una función miembro sin una instancia de un objeto?

Para actualizar esto, si decide pasar uno de estos objetos std :: function como un parámetro a alguna otra función, descubrí que necesitaba usar std :: function :: assign, o la asignación resultaría en una copia superficial. Esto puede ser un problema si intenta pasarlo a un objeto con un ciclo de vida más largo que el original.

Ejemplo:

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 ); ... }