Ich spiele mit Std :: Funktion und benutzerdefinierte Allokatoren, aber es verhält sich nicht wie erwartet, wenn ich die Funktion nicht mit einem anfänglichen Funktor zur Verfügung stellen.Was ist der Punkt des Konstruktors std :: function mit benutzerdefiniertem Zuordner, aber keine anderen Argumente?
Wenn ich dem Konstruktor einen benutzerdefinierten Zuordner, aber keinen anfänglichen Funktor zur Verfügung stelle, wird der Zuordner niemals verwendet, oder so scheint es.
Dies ist mein Code.
//Simple functor class that is big to force allocations
struct Functor128
{
Functor128()
{}
char someBytes[128];
void operator()(int something)
{
cout << "Functor128 Called with value " << something << endl;
}
};
int main(int argc, char* argv[])
{
Allocator<char, 1> myAllocator1;
Allocator<char, 2> myAllocator2;
Allocator<char, 3> myAllocator3;
Functor128 myFunctor;
cout << "setting up function1" << endl;
function<void(int)> myFunction1(allocator_arg, myAllocator1, myFunctor);
myFunction1(7);
cout << "setting up function2" << endl;
function<void(int)> myFunction2(allocator_arg, myAllocator2);
myFunction2 = myFunctor;
myFunction2(9);
cout << "setting up function3" << endl;
function<void(int)> myFunction3(allocator_arg, myAllocator3);
myFunction3 = myFunction1;
myFunction3(19);
}
Ausgang:
setting up function1
Allocator 1 allocating 136 bytes.
Functor128 Called with value 7
setting up function2
Functor128 Called with value 9
setting up function3
Allocator 1 allocating 136 bytes.
Functor128 Called with value 19
So case1: MyFunction1 teilt mit allocator1 wie erwartet.
case2: myFunction2 wird im Konstruktor allocator2 zugewiesen, aber wenn ein Funktor zugewiesen wird, scheint er auf den standardmäßigen std :: allocator zurückgesetzt zu werden, um die Zuweisung vorzunehmen (daher kein Ausdruck über Zuweisung).
case3: myFunction3 erhält im Konstruktor allocator3, aber bei Zuordnung von myFunction1 erfolgt die Zuweisung mit dem Zuweisungsmodul von function1, um die Zuweisung vorzunehmen.
Ist das korrektes Verhalten? Insbesondere im Fall 2, warum zurück zur Verwendung von Standard-std :: allocator? Wenn ja, was ist der Punkt des leeren Konstruktors, der einen Zuordner verwendet, da der Zuordner niemals verwendet wird.
Ich verwende VS2013 für diesen Code.
Meine Allocator Klasse ist nur eine minimale Implementierung, die neu verwendet und sich abmeldet, wenn es
template<typename T, int id = 1>
class Allocator {
public:
// typedefs
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
public:
// convert an allocator<T> to allocator<U>
template<typename U>
struct rebind {
typedef Allocator<U> other;
};
public:
inline Allocator() {}
inline ~Allocator() {}
inline Allocator(Allocator const&) {}
template<typename U>
inline Allocator(Allocator<U> const&) {}
// address
inline pointer address(reference r) { return &r; }
inline const_pointer address(const_reference r) { return &r; }
// memory allocation
inline pointer allocate(size_type cnt,
typename std::allocator<void>::const_pointer = 0)
{
size_t numBytes = cnt * sizeof (T);
std::cout << "Allocator " << id << " allocating " << numBytes << " bytes." << std::endl;
return reinterpret_cast<pointer>(::operator new(numBytes));
}
inline void deallocate(pointer p, size_type) {
::operator delete(p);
}
// size
inline size_type max_size() const {
return std::numeric_limits<size_type>::max()/sizeof(T);
}
// construction/destruction
inline void construct(pointer p, const T& t) { new(p)T(t); }
inline void destroy(pointer p) { p->~T(); }
inline bool operator==(Allocator const&) { return true; }
inline bool operator!=(Allocator const& a) { return !operator==(a); }
}; // end of class Allocator
Es gibt einen Vorschlag allocator Unterstützung von 'std :: function' zu entfernen: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0302r0.html einer hilfreichen Liste Bekannte Probleme –