【发布时间】:2019-11-01 18:14:08
【问题描述】:
我正在使用第三方 C 库 (Raylib),其中包含宏和 struct 在标头中定义如下:
// raylib.h
#define RED { 230, 41, 55, 255 } // Red
// Color type, RGBA (32bit)
typedef struct Color {
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
} Color;
我想将它封装在我自己的 C++ 头文件和名为 engine.h 和 engine.cc 的源文件中,它们只公开相关的函数和宏。
为了确保只有engine.cc 可以访问标头raylib.h,我希望:
- 在
engine.h中转发声明struct Color和 -
#include "raylib.h"仅在engine.cc
类似这样的东西 (source):
// engine.h
// Forward declare.
struct Color;
typedef struct Color Color;
namespace Engine {
namespace Colors {
const extern Color Red;
}
void SetBackgroundColor(Color color);
};
// engine.cc
#include "engine.h"
#include "raylib.h"
namespace Engine {
namespace Colors {
const Color Red = RED;
}
void SetBackgroundColor(Color color) {
::SetBackgroundColor(color);
}
}
不幸的是,这不起作用,因为我无法转发声明 typedef,因为它也在 typedef 中定义了结构。
我的问题是,如果我想对包括 engine.h 在内的所有其他文件隐藏 raylib.h,最好的选择是什么?
我尝试过并且有效的一种方法是拥有自己的颜色enum class,然后由位于engine.cc 中的匿名命名空间中的辅助函数解析。辅助函数使用switch 语句解决它。但这很乏味,因为我需要为我想使用的每种新颜色编写大量代码。此外,Color 只是具有关联宏的结构之一。还有很多,我不想为每一个都创建这些辅助函数。
【问题讨论】:
-
为什么是
typedef Color color? -
您的代码为我编译:godbolt.org/z/1XGgu1,请显示minimal reproducible example
-
@AlanBirtles - 谢谢。它可以编译,但
engine.h中的Color与engine.cc中的Color不同。当您尝试使用SetBackgroundColor(Engine::Colors::Red)时,它会显示Cannot cast from Color to Color。 -
@AlanBirtles - 关于
typedef Color Color,抱歉,我本来打算写typedef struct Color Color。 -
关于
structs(以及unions 和enums),C 和C++ 之间存在区别:在C 中,struct Color只能用作struct Color.因此,为方便起见,typedef struct Color { } Color;。在 C++ 中,struct Color可以用作Color。struct的标识符成为类型的名称 - 更方便(恕我直言)。因此,C++ 中不需要像 C 中这样的typedefs。