Hallo C++ Speziallisten,
ich habe vermutlich ein Verständnisproblem bei der Nutzung der Standard
C++ String Klasse in Verbindung mit einem eigenen allocator. Das Ziel
ist, bestimmte Strings gesondert im Speicher abzulegen, und dabei
ansonsten völlig kompatibel zu den "normalen" Strings zu sein. Mein
minimales Beispiel:
#include <iostream>
class myalloc : public std::allocator<char>
{
template<typename T>
T* allocate(std::size_t n, const void* = 0)
{
std::cout << "myalloc::allocate(" << n << ")\n";
if(100 < n) throw std::bad_alloc();
return static_cast<T*>(&_memory);
}
private:
unsigned char _memory[100];
};
myalloc customAllocator;
int main()
{
std::string mystring(customAllocator);
std::string regularString = "test string\n";
mystring = regularString;
std::cout << mystring;
}
Sowohl GCC (als auch Clang und zapcc auf Wandbox (
https://wandbox.org/))
akzeptieren den Code, rufen aber nie die spezielle allocate Methode auf,
sondern nach wie vor die von std::allocator.
Beim Versuch, das Verhalten zu verstehen, bin ich in den Tiefen der GCC
C++ Standardbibliothek (bits/basic_string.tcc, in verschiedenen GCC 4er
und 6er Versionen) über folgende Zeile gestolpert:
void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
"__alloc" dürfte hier noch mein Allocator sein, aber "_Raw_bytes_alloc "
ist ein typedef des std::allocator in bits/basic_string.h:
typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
"rebind<char>::other" ist wiederum mehr oder weniger ein typedef auf
sich selbst in bits/allocator.h:
template<typename _Tp1>
struct rebind
{ typedef allocator<_Tp1> other; };
};
Für mich liest sich das so, als ob die Standard C++ String Klasse des
GCC hier vor dem Aufruf der "allocate" Methode einen expliziten Cast auf
die Klasse des Allocator der Datentypdefinition machen, anstatt die
speziell angegebene zu verwenden.
Ist dieses Verhalten standard-konform?
Wenn ja, warum; wo liegt mein Denkfehler?
Danke schon mal im Voraus für die Erklärung,