我有一个带有 MS Visual Studio 2015 的大型 C++11 项目,它在两个模块(= 编译单元、cpp 文件)中定义了两个名称相同但内容不同的结构。由于结构仅在模块内定义和使用,而不是通过任何头文件导出以供共享使用,因此应该允许这样做,而且实际上编译器和链接器都不会报告任何错误或警告。但是在运行时,我从包含该结构的无序映射的构造函数中得到了访问冲突。 Visual Studio 2017 也会出现此问题,但 gcc5.4 不会。在我看来,这是一个编译器错误,但我不确定。 这里有一些最小化的源代码来重现问题,只需链接任何可执行文件即可在 main() 之前的启动期间获取访问冲突。
模块1.cpp:
#include <unordered_map>
struct AmbigousStruct {
int i1;
int i2;
int i3;
};
static const std::unordered_map<int, AmbigousStruct>
s_ambigousStructMap{
{ 0, { 0, 1, 2 } }
};
模块2.cpp:
#include <unordered_map>
struct AmbigousStruct {
int i1;
int i2;
};
static const std::unordered_map<int, AmbigousStruct>
s_ambigousStructMap{
{ 0, { 0, 1 } }
};
问题似乎与在模板类(本例中为 unordered_map)中使用结构有关,因为它不会发生在结构的简单实例中,即 module2.cpp:
static const AmbigousStruct s_ambigousStructInstance{ 0, 1 };
最佳答案
您有两个具有外部链接的类类型,具有相同的名称,在不同的翻译单元中定义。他们的成员不匹配,这违反了单一定义规则。您的程序格式错误,无需诊断。
您需要对该结构定义强制进行内部链接。 C++ 标准允许您使用匿名命名空间来做到这一点。事实上,匿名 namespace 使其中的一切 都具有内部链接。所以你不需要 static
修饰符来做其他事情:
namespace {
struct AmbigousStruct {
int i1;
int i2;
};
const std::unordered_map<int, AmbigousStruct>
s_ambigousStructMap {
{ 0, { 0, 1 } }
};
}
关于c++ - 不同模块中的结构定义不明确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46999413/