std::unordered_map
から継承するクラステンプレートを宣言する場合のVisual Cで動作しているとき、私はテンプレート引数の間違ったサイズを取得してい++ 2015間違ってはsizeof()のVisual Cにunordered_mapから継承++
Ubuntuの64ビットで期待どおり
g++ -std=c++11 test.cpp
は以下を出力してコンパイル時に以下のコードは、動作します:
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
しかし、ビジュアルでC++ 2015の64ビットマシン上で、私が取得しています:
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
を私はstd::unordered_map
から継承しない場合は、すべてがUbuntuの上とVC2015の両方で正常に動作します。私はここで何が欠けていますか? - それは含まれて
#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();
};
私はそれが 'bool'と' unsigned long long'の間でコンパイラによって追加されたパディングと関係していると思います。さらに、仮想関数を宣言する(おそらく)クラスから継承するときに、クラスに追加されるVテーブルポインタをチェックします。異なるコンパイラが、異なる実装を使用している可能性があります(この場合、これが問題であるとは考えていますが)。 –
['std :: unordered_map'](http://en.cppreference.com/w/cpp/container/unordered_map)は継承するようには設計されておらず、仮想デストラクタもありません。むしろ、*仮想関数はありませんが、それはあなたの背後で最もよく噛み砕く仮想デストラクタの欠如です。インタフェースの一部を継承したい場合は、プライベート継承を使用する可能性があります。 –
Joachimの言葉に従う: 'std :: unordered_map'から継承しないでください。 (is-aではなくhas-aを使用します)。 –