Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从visual c+;中的无序映射继承时,模板参数的sizeof()不正确+; 当声明继承自 STD::unOrdEdMultMux/Cuff>的类模板时,在VisualC++ 2015中运行时,模板参数的大小错误。p>_C++_Inheritance_Visual Studio 2015_Sizeof_Unordered Map - Fatal编程技术网

从visual c+;中的无序映射继承时,模板参数的sizeof()不正确+; 当声明继承自 STD::unOrdEdMultMux/Cuff>的类模板时,在VisualC++ 2015中运行时,模板参数的大小错误。p>

从visual c+;中的无序映射继承时,模板参数的sizeof()不正确+; 当声明继承自 STD::unOrdEdMultMux/Cuff>的类模板时,在VisualC++ 2015中运行时,模板参数的大小错误。p>,c++,inheritance,visual-studio-2015,sizeof,unordered-map,C++,Inheritance,Visual Studio 2015,Sizeof,Unordered Map,下面的代码在使用 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 但是在64位机器上的Visual C++ 20

下面的代码在使用

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

但是在64位机器上的Visual C++ 2015中,我得到:

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();
};
#包括
#包括
#包括
#包括
将my_key_类型分类{
无符号整数_int1;
无符号整数_int2;
无符号短路_short1;
无符号短路_short2;
公众:
布尔运算符==(常数我的键类型和其他键)常数{
return(memcmp(this,&other_key,sizeof(my_key_type))==0);
};
};
名称空间标准{
模板结构哈希{
std::size\u t运算符()(常量my\u key\u type&key)常量{
返回std::hash();
};
};
};
分类我的值类型{
布卢旗;
无符号长-长计数1;
无符号长-长计数2;
};
#定义从\u无序\u映射1继承\u
#if(从\u无序\u映射继承\u==0)
模板类kv_图{
#否则
模板类kv_图:公共标准::无序_图{
#恩迪夫
公众:
无效测试_打印(){
printf(“内部:sizeof(my_key_type)=%ld,sizeof(my_value_type)=%ld\n”,sizeof(my_key_type),sizeof(my_value_type));
printf(“内部(WTF?):sizeof(键类型)=%ld,sizeof(值类型)=%ld\n,sizeof(键类型),sizeof(值类型));
};
};
int main(){
printf(“外部:sizeof(my_key_type)=%ld,sizeof(my_value_type)=%ld\n”,sizeof(my_key_type),sizeof(my_value_type));
千伏地图;
map.test_print();
};

std::无序映射
有一个名为
value\u type的类型

value_type  std::pair<const Key, T>
value\u类型std::pair
几乎可以肯定的是,你正在接受这一点——因为这也包括关键数据


更改模板类型的名称,看看会发生什么。

std::unordered\u map
有一个名为
value\u type

value_type  std::pair<const Key, T>
value\u类型std::pair
几乎可以肯定的是,你正在接受这一点——因为这也包括关键数据


更改模板类型的名称,看看会发生什么。

问题是,imho,类型的查找优先于
键类型
值类型

您选择使用已存在于
std::unordered_map
类中的两个类型名

using value_type = pair<const K, V>;

如果您从
无序映射中强制使用
值类型
,您将得到40个字节。

问题是,imho,类型
键类型
值类型
的查找优先

您选择使用已存在于
std::unordered_map
类中的两个类型名

using value_type = pair<const K, V>;

如果您强制使用
无序映射中的
值类型
,您将得到40个字节。

我相信这是VS无法进行两阶段查找的一种情况

非模板基类的名称将隐藏派生类模板参数的名称。例如:

class A
{
public:
   int   T:
};

template<typename T>
class B : A
{
   // here T will mean A::T and not the template parameter
};
A类
{
公众:
int T:
};
样板
B类:A
{
//这里T表示A::T,而不是模板参数
};
另一方面,如果基类是一个模板,那么在第1阶段名称查找过程中,它的本地名称是未知的,因此名称必须绑定到该点上可见的内容

template<typename X>
class A
{ };

template<>
class A<int>
{
   using T = float;
};

template<typename T>
class B : A<T>
{
   // here a possible A::T is not visible at phase 1
   // so T must mean B::T
};
模板
甲级
{ };
样板
甲级
{
使用T=浮动;
};
样板
B类:A
{
//在第1阶段,可能的a::T不可见
//所以T一定是指B::T
};

众所周知,VC++在模板实例化之前不会执行名称查找。当时它知道实际参数和实际基类型,并且显然将案例2视为案例1。

我相信这是VS无法执行两阶段查找的一种情况

非模板基类的名称将隐藏派生类模板参数的名称。例如:

class A
{
public:
   int   T:
};

template<typename T>
class B : A
{
   // here T will mean A::T and not the template parameter
};
A类
{
公众:
int T:
};
样板
B类:A
{
//这里T表示A::T,而不是模板参数
};
另一方面,如果基类是一个模板,那么在第1阶段名称查找过程中,它的本地名称是未知的,因此名称必须绑定到该点上可见的内容

template<typename X>
class A
{ };

template<>
class A<int>
{
   using T = float;
};

template<typename T>
class B : A<T>
{
   // here a possible A::T is not visible at phase 1
   // so T must mean B::T
};
模板
甲级
{ };
样板
甲级
{
使用T=浮动;
};
样板
B类:A
{
//在第1阶段,可能的a::T不可见
//所以T一定是指B::T
};

众所周知,VC++在模板实例化之前不会执行名称查找。当时它知道实数参数和实数基类型,并且显然将案例2视为案例1。

我猜这与编译器在
bool
和以下
unsigned long
之间添加的填充有关。此外,我会检查从声明虚拟函数的类继承时添加到类中的V-table指针。不同的编译器可能会为此使用不同的实现(尽管我怀疑这是本例中的问题)。不是为继承而设计的,它没有虚拟析构函数。或者更确切地说,它没有任何虚拟函数,但它缺少虚拟析构函数,这将使您在后面遭受最大的损失。如果您想继承接口的一部分,那么您可以使用私有继承。遵循Joachim的说法:我不需要吗nherit from
std::unordered\u map
-包含它。(使用has-a,而不是is-a)。我猜它与编译器在
bool