Pet*_*aro 7 c++ namespaces header wrapper c++11
我正在尝试用C++包装一个C库,使其成为一个现代的,高水平的,惯用的C++库.我想要做的是使C对象完全不透明和/或直接从C++代码中不可用,并用更高级别的替代品包装/替换它们.
我面临的问题很简单:我想只将C头包含在C++源代码中,这样C++头文件在包含时也不会包含C头文件的声明,也就是说,它不会污染C++头部.全局命名空间
但看起来头文件和源文件的正确分离似乎不允许我这样做.这是我的问题的一个非常模糊的版本,评论会告诉你其余的:
my_header.h:
typedef enum
{
my_Consts_ALPHA = /* some special value */,
my_Consts_BETA = /* other special value */,
} my_Consts;
typedef struct
{
// members...
} my_Type;
void
my_Type_method(my_Type *const,
my_Enum);
Run Code Online (Sandbox Code Playgroud)
my_header.hpp:
namespace my
{
enum class Consts; // <-- This header is missing the constant values of
// this enum, because its values are defined by
// the C header :(
class Type : public my_Type // <-- The super struct is coming from the
// C header, but I don't want to include
// that header here :(
{
public:
void
method(Consts constant);
};
}
Run Code Online (Sandbox Code Playgroud)
my_source.cpp:
extern "C"
{
#include "my_header.h"
}
#include "my_header.hpp"
namespace my
{
enum class Consts
{
ALPHA = my_Consts_ALPHA,
BETA = my_Consts_BETA,
};
void
Type::method(Consts constant)
{
my_Type_method(static_cast<my_Type *const>(this),
static_cast<my_Consts>(constant));
}
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:我错过了一些非常明显的东西吗?这有可能实现吗?有没有我不知道的伎俩?
在问题的评论中@AnalPhabet讽刺地建议,应该#include在namespace. @nm证实,它实际上是一个有效的解决方案,现在我在自己的设置上测试了它,幸运的是它工作得很好。
(虽然我不知道这是否是特定于实现的,但我对两者进行了测试g++,并且clang++它正在工作。)
它没有解决不透明问题,但至少它使直接访问原始 C 数据变得更加困难,因为它现在处于单独的状态namespace,因此用户不能意外访问,而是愿意访问。
所以,my_header.hpp应该是这样的:
namespace my
{
extern "C"
{
#include "my_header.h"
}
enum class Consts
{
ALPHA = my_Consts_ALPHA,
BETA = my_Consts_BETA,
};
class Type : public my_Type
{
public:
void
method(Consts constant);
};
}
Run Code Online (Sandbox Code Playgroud)
因此无论my_header.hpp是#include'd 处,用户都只能访问 C 值,如下所示:
my::my_Consts_ALPHA // The wrapped value is => my::Consts::ALPHA
my::my_Type // The wrapped value is => my::Type
my::my_Type_method(t,..) // The wrapped value is => t.method(..)
Run Code Online (Sandbox Code Playgroud)