C++ 无法向前声明C typedef结构-正在寻找其他建议
我使用的是第三方C库(),它的头中定义了宏和C++ 无法向前声明C typedef结构-正在寻找其他建议,c++,c++17,C++,C++17,我使用的是第三方C库(),它的头中定义了宏和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++头文件和名为e
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
,并#仅在engine.cc
engine.h
的所有其他文件隐藏raylib.h
,最好的选择是什么
我尝试过的一种有效方法是拥有自己的
enum类
,这些颜色由engine.cc
中匿名命名空间中的帮助函数解析。helper函数使用开关
语句解析它。但这是乏味的,因为我需要为我想要使用的每种新颜色编写大量代码。而且,Color
只是具有关联宏的结构之一。还有很多,我不想为它们中的每一个创建这些帮助函数。我解决了这个问题,但在一个命名空间中定义了我自己的结构颜色
,该命名空间与raylib.h
中的命名空间相同,并在engine.cc
中创建了一个将一个转换为另一个的帮助函数
// engine.h
namespace Engine {
namespace Colors {
struct Color {
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
};
extern const Color Red;
extern const Color Green;
extern const Color Blue;
extern const Color Black;
} // namespace Colors
void SetBackgroundColor(const Colors::Color);
} // namespace Engine
// engine.cc
namespace Engine {
using RayColor = ::Color;
namespace Colors {
const Color Red = RED;
const Color Green = GREEN;
const Color Blue = BLUE;
const Color Black = BLACK;
namespace {
RayColor GetRayColor(const Color color) {
return RayColor{color.r, color.g, color.b, color.a};
}
} // namespace
} // namespace Colors
void SetBackgroundColor(const Colors::Color color) {
::ClearBackground(Colors::GetRayColor(color));
}
} // namespace Engine
这是因为我可以轻松地从Engine::Colors::Color
转换为Color
。另外,因为所有颜色宏都只是大括号中的数字,所以我可以轻松地使用它们来指定给我自己的结构
当然,此解决方案特定于raylib.h
和我的需求。我希望这个问题有一个更普遍的解决办法
我不确定这种方法对性能的影响有多大,但我现在会尝试一下,如果有任何问题,我会重新访问。为什么
typedef Color
?您的代码为我编译:,请显示@AlanBirtles-谢谢。它可以编译,但是engine.h
中的Color
与engine.cc
中的Color
不同。当你尝试使用SetBackgroundColor(Engine::Colors::Red)
时,它会说不能从颜色转换到颜色
@AlanBirtles-关于typedef Color
,对不起,我的意思是写typedef struct Color
。关于struct
s(和union
s和enum
s),C和C++之间有一个区别:在C中,struct Color
只能用作struct Color
。因此,typedef结构颜色{}Color代码>为方便起见。在C++中,结构颜色> /COD>可以用作<代码>颜色< /代码>。struct
的标识符成为类型的名称-更方便(IMHO)。所以,在C++中不需要像C那样的<<代码> TyPulf S。IMO这是过于复杂的问题,只是为以后的人(包括你自己)创建未来的头痛,试图读取代码,并想知道为什么F会这样做。this@M.M-我同意你的看法。我希望我不必这么做。但现在,这是我能想到的最好的选择。除了必须在标题engine.h
中包含raylib.h
之外,我对其他选择持开放态度。我希望有一个更通用的解决方案来解决这个问题。C++20将引入模块,我希望这将是一个更通用的解决方案。@Eljay-我看过模块,不确定它们在这种情况下是否有用。解决这个问题的唯一方法是,我可以在没有完整定义的情况下(而不仅仅是指针或对前向声明类型的引用)前向声明类型和变量。
// engine.h
namespace Engine {
namespace Colors {
struct Color {
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
};
extern const Color Red;
extern const Color Green;
extern const Color Blue;
extern const Color Black;
} // namespace Colors
void SetBackgroundColor(const Colors::Color);
} // namespace Engine
// engine.cc
namespace Engine {
using RayColor = ::Color;
namespace Colors {
const Color Red = RED;
const Color Green = GREEN;
const Color Blue = BLUE;
const Color Black = BLACK;
namespace {
RayColor GetRayColor(const Color color) {
return RayColor{color.r, color.g, color.b, color.a};
}
} // namespace
} // namespace Colors
void SetBackgroundColor(const Colors::Color color) {
::ClearBackground(Colors::GetRayColor(color));
}
} // namespace Engine