【问题标题】:Split declaration and defintion of c++ enum classc++枚举类的拆分声明和定义
【发布时间】:2019-08-05 13:34:07
【问题描述】:

我想通过以下方式使用枚举类

// Foo.h
enum class Foo : uint8_t;

// Foo.cpp
enum class Foo : uint8_t {
  FOO = 0,
};

// Bar.cpp
enum class Foo : uint8_t {
  FOO = 1,
};

// MainLinkedWithFoo.cpp
#include "Foo.h"
int main () {
  (void)Foo::FOO;
  return 0;
}

// MainLinkedWithBar.cpp
#include "Foo.h"
int main () {
  (void)Foo::FOO;
  return 0;
}

但我得到以下错误

在嵌套名称说明符中命名的不完整类型“Foo”

有人知道如何解决这个“问题”吗?

谢谢

【问题讨论】:

    标签: class c++11 enums


    【解决方案1】:

    您可以前向声明作用域枚举,但在您引用实际枚举标识符(例如Foo::FOO)时,编译器必须可以使用完整的枚举定义。

    大多数情况下,作用域枚举既不是通过接口传递的实现细节,也不是编译时间的瓶颈。因此,直接的解决方法是将定义放入头文件中。

    // Foo.h
    enum class Foo : uint8_t {
      FOO = 0,
      BAR = 1
    };
    

    但是当您明确要求单独的声明和定义时,您可能想要这样:

    // FooFwd.h
    enum class Foo : uint8_t;
    

    Foo.h 中的定义同上。然后,每当您想使用枚举实例而不引用其实际枚举数时,您只需#include "FooFwd.h",如果您需要访问例如Foo::FOO,请使用#include "Foo.h"

    【讨论】:

    • 我不想在 Foo.h 或 FooFwd.h 中分配任何值。这些值只能在 .cpp 文件中使用/分配。
    • 如果在某个翻译单元中定义枚举,则只能在该翻译单元内引用其枚举数。枚举将毫无用处。此外,提供多个定义作为您的问题的编辑现在显示是违反一个定义规则。你应该只定义一次。
    • 不明白一个定义规则问题"g++ MainLinkedWithFoo.cpp Foo.cpp" or "g++ MainLinkedWithBar.cpp Bar.cpp"
    • 好的,我明白了,您不会将两个定义链接到一个可执行文件中。然后没有 ODR 违规,但如果没有手头的定义,您仍然不能引用 Foo::FOO
    猜你喜欢
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多