名称/命名空间相同但成员不同的结构 [英] Structs with the same name/namespace but different members

查看:107
本文介绍了名称/命名空间相同但成员不同的结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到我在这篇文章中描述的一些奇怪的行为结构内联初始化向量。 braced-init-list

I am seeing some strange behavior which I have described in this post vector of structs inline initialization. braced-init-list

我希望消除未定义行为的一种可能来源。我有以下两个类 A B 都向前声明 struct Foo ,但cpp文件定义的实际结构如下。

I am hoping to eliminate one possible source of the undefined behavior. I have the following two classes A and B which both forward declare struct Foo but the cpp file defines the actual struct as below.

// This is A.h
namespace app {
    struct Foo;
    class A {
    private:
        std::vector<Foo> fooList;
    };
}

// This is A.cpp
struct app::Foo {
    std::string first;
    std::string second;
    unsigned flag;
};


// This is B.h
namespace app {
    struct Foo;
    class B {
    private:
        std::vector<Foo> fooList;
    };
}

// This is B.cpp
struct app::Foo {
    std::string first;
    std::string second;
    bool flag;
    float value;
};

注意,结构 Foo 具有不同的结构cpp文件 A.cpp B.cpp 中的成员。类 A B 从不公开成员 fooList 。是否有可能因为前向声明完全相同,所以在结构<$的文件 Ah Bh 中c $ c> Foo ,生成的代码可能正在使用其中之一。这可以解释我在链接问题中看到的问题。

Notice, that the struct Foo has different members in cpp files A.cpp, B.cpp. The classes A and B never expose the member fooList. Is it ever possible that since the forward declaration is exactly the same, in files A.h and B.h for the struct Foo, the generated code could be using one or the other. This could explain the issue I was seeing in the linked problem.

换句话说,在对<$ c $中调用的结构 Foo 使用花括号初始化列表时c> B.cpp 是否保证 B.cpp 中定义的 Foo 是否使用过,或者是否也有可能使用 A.cpp 中定义的 Foo

In other words, while using the braced-init-list for the struct Foo invoked in B.cpp is it guaranteed that Foo defined in B.cpp would be used or it is equally likely that Foo defined in A.cpp could also be used?

即使我在写这篇文章,我也立即意识到这种实现是一种不好的做法,因为 Foo 本身是<$ c类的内部$ c> A 和 B ,实际上应该在类本身的私有部分中声明。

Even as I am writing this, I immediately realize that this implementation is a bad practice as Foo itself is internal to the classes A and B and should really have been declared in the private section of the class itself.

推荐答案

这违反了ODR(一种定义规则)。

This violates the ODR (one definition rule).

程序格式错误,无诊断信息

The program is ill-formed, no diagnostic required.

如果这样做,C ++标准绝对允许任何行为。它可以工作,可以选择一个并丢弃另一个,可以工作直到重新链接,然后可以格式化硬盘。

Absolutely any behavior is permitted by the C++ standard if you do this. It could "work", it could pick one and discard the other, it could work until you relink, it could format your hard drive.

真实的现场项目;我们有一个矩阵标头,可以在其中包含令牌(如果它支持浮点或双精度),可以在其中定义令牌。

I have done this in a real live project; we had a matrix header where you could define tokens before including it if it would support float or double.

此有效方法是我们从未在同一DLL中使用两个版本。然后我们使用这两个版本。

This "worked" while we never used both versions in the same DLL. Then we used both versions.

编译器将基于一组巧合为结构选择一个大小或另一种大小,并基于巧合略有不同。我们有大量的内存破坏问题。

The compiler would pick one size or the other for the structure based on one set of coincidences, and would pick one constructor or other based off a slightly different set of coincidences. We got memory corruption galore. But only sometimes on some builds.

我们通过将代码包装在名称空间中(名称中包含标量类型),然后使用来快速修复它。 将它们带入外部名称空间。

We quickly "fixed" it by wrapping the code in a namespace whose name included the scalar type, then using brought them into the exterior namespace.

这篇关于名称/命名空间相同但成员不同的结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆