Incorrect sizeof() of template argument when inheriting from unordered_map in visual c++

Erez Buchnik

When declaring a class template that inherits from std::unordered_map, I'm getting the wrong size of the template argument when running in Visual C++ 2015.

The code below works as expected on Ubuntu 64-bit, when compiled with

g++ -std=c++11 test.cpp

outputting the following:

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

But in Visual C++ 2015 on a 64-bit machine, I'm getting:

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

If I don't inherit from std::unordered_map, then everything works fine both on Ubuntu and in VC2015. What am I missing here?

Thanks in advance for your help - here's the 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();
};
xaxxon

std::unordered_map has a type called value_type

value_type  std::pair<const Key, T>

It's almost certainly that you're picking that up - as that includes the key data as well.

Change the name of your templated type and see what happens.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Visual Studio Intellisense not working when inheriting from template class

C2535 with template-class in unordered_map (Microsoft Visual Studio 2015 CTP6)

C++ custom template with unordered_map

"No argument given" when inheriting from a class

C++17 Inheriting set of lambdas with template argument deduction guides

C++ Template Parameter sizeof Returns Incorrect Result

Template argument deduction for inheriting specializations

Inheriting from a template class in c++ with enum as template parameter

Template base class accessible when inheriting from a specific specialization?

Ambiguous base class when inheriting from template class with auto parameter

Inheriting from a template class using the inheriting class

C++: segfault when accessing data in unordered_map to set

Visual Studio Class Icon Changes When Inheriting from WebClient

metaclass error when inheriting from psychopy.visual.DotStim

Incorrect output when using sizeof()

unordered_map in a function argument

accessing values from unordered_map in c++

Inheriting a constructor from a private template class in C++

C++: Inheriting from template class with possible varying constructor arguments

Inheriting from a template class using the inheriting class with C++20 concepts

C2516 Error in inheriting from a lambda in Visual Studio 2013

Inheriting from template abstract class

C++ - "unspecialized class template" in unordered_map with shared_ptr to template class

Inheriting from a template with a member class of the inheriting class as a template parameter

How to write a C++ concept restricting the template to std::map and std::unordered_map

Template object manager, incorrect argument

C++ template specialization not working when comparing sizeof(type) == constant

could not deduce template argument for T* from FieldType* (Visual C++ only)

Initialization of members when inheriting from extern C struct