Wenn eine Klassenvorlage erklärt, die von std::unordered_map
erbt, erhalte ich die falsche Größe der Vorlage Argument, wenn in Visual C läuft ++ 2015Falsche sizeof() der Template-Argument, wenn sie von unordered_map in visual c vererben ++
Die Code unten funktioniert wie auf Ubuntu 64-Bit erwartet, wenn sie mit
g++ -std=c++11 test.cpp
Ausgeben der folgenden zusammengestellt:
OUTSIDE: sizeof(my_key_type) = 12, sizeof(my_value_type) = 24
INSIDE: sizeof(my_key_type) = 12, sizeof(my_value_type) = 24
INSIDE(WTF?): sizeof(key_type) = 12, sizeof(value_type) = 24
Aber in Visual C++ 2015 auf einer 64-Bit-Maschine, ich bin immer:
OUTSIDE: sizeof(my_key_type) = 12, sizeof(my_value_type) = 24
INSIDE: sizeof(my_key_type) = 12, sizeof(my_value_type) = 24
INSIDE(WTF?): sizeof(key_type) = 12, sizeof(value_type) = 40
Wenn ich von std::unordered_map
nicht erbt, dann alles, was sowohl auf Ubuntu und in VC2015 gut funktioniert. Was fehlt mir hier?
Vielen Dank im Voraus für Ihre Hilfe - hier ist der Code:
#include <stdio.h>
#include <string.h>
#include <string>
#include <unordered_map>
class my_key_type {
unsigned int _int1;
unsigned int _int2;
unsigned short _short1;
unsigned short _short2;
public:
bool operator == (const my_key_type &other_key) const {
return (memcmp(this, &other_key, sizeof(my_key_type)) == 0);
};
};
namespace std {
template <> struct hash<my_key_type> {
std::size_t operator()(const my_key_type &key) const {
return std::hash<string>()(std::string((const char *)&key, sizeof(my_key_type)));
};
};
};
class my_value_type {
bool _flag;
unsigned long long _count1;
unsigned long long _count2;
};
#define INHERITS_FROM_UNORDERED_MAP 1
#if (INHERITS_FROM_UNORDERED_MAP == 0)
template <typename key_type, typename value_type> class kv_map {
#else
template <typename key_type, typename value_type> class kv_map : public std::unordered_map<key_type, value_type> {
#endif
public:
void test_print() {
printf("INSIDE: sizeof(my_key_type) = %ld, sizeof(my_value_type) = %ld\n", sizeof(my_key_type), sizeof(my_value_type));
printf("INSIDE(WTF?): sizeof(key_type) = %ld, sizeof(value_type) = %ld\n", sizeof(key_type), sizeof(value_type));
};
};
int main() {
printf("OUTSIDE: sizeof(my_key_type) = %ld, sizeof(my_value_type) = %ld\n", sizeof(my_key_type), sizeof(my_value_type));
kv_map<my_key_type, my_value_type> map;
map.test_print();
};
Ich würde vermuten, dass es etwas mit Padding zu tun hat, die vom Compiler zwischen dem 'bool' und dem folgenden' unsigned long long' hinzugefügt wurde. Außerdem würde ich den V-Tabellenzeiger überprüfen, der zu Ihrer Klasse hinzugefügt wird, wenn er von einer (vermutlich) Klasse erbt, die virtuelle Funktionen deklariert. Verschiedene Compiler verwenden dafür möglicherweise verschiedene Implementierungen (obwohl ich bezweifle, dass dies in diesem Fall der Fall ist). –
['std :: unordered_map'] (http://en.cppreference.com/w/cpp/container/unordered_map) ist nicht darauf ausgelegt, von geerbt zu werden, es hat keinen virtuellen Destruktor. Oder es hat keine * virtuellen * Funktionen, aber es ist das Fehlen eines virtuellen Destruktors, der Sie am meisten im Hinterteil gebissen wird. Wenn Sie einen Teil der Schnittstelle erben möchten, können Sie möglicherweise private Vererbung verwenden. –
Um dem zu folgen, was Joachim sagt: Erben Sie nicht von 'std :: unordered_map' - enthalten Sie es. (Verwenden Sie has-a, nicht is-a). –