如何使用模板化C++结构定义 C 向前声明的不透明结构
How to define C-forward declared opaque struct with a templated C++ struct
给定不透明类型的C声明(cheader.h(
typedef struct internal_data * Opaque;
我想声明"internal_data"作为模板的实例(cppheader.h(
namespace Lib {
template<typename T>
struct Internal {
T data;
};
template<typename T>
Internal<T>* Initialise(T data) {
Internal<T>* t = new Internal<T>();
t->data = data;
return t;
}
}
以便编译以下函数:
#include "cppheader.h"
#include "cheader.h"
int main(int argc, char** argv)
{
Opaque o = Lib::Initialise(argc);
return 0;
}
我无法修改 C 标头。C++标题没有公开,所以我可以随意修改该标头。实例化的模板必须是 POD。为了简单起见,我省略了 C 标头上的多个不透明类型。它们都应该取消对C++模板实例的引用。
我试过了
typedef Lib::Internal<int> internal_data;
和
struct internal_data : Lib::Internal<int> {};
但两者都不编译。
如果你不想reinterpret_cast<>
,你可以从虚拟internal_data
继承,即
struct internal_data {};
template<typename T>
struct Internal: internal_data {
T data;
};
当您需要访问数据时,只需从指针向下转换为模板类型。
据我所知,这看起来像是典型的 C 到 C++ API 映射,反之亦然。
鉴于无法更改 C 头文件,则 Opaque
的定义受到约束,基本上无法键入到头文件中包含的任何C++构造C++。
纯粹的意义上,它有点丑陋,但你可以为此使用reinterpret_cast
。
在 cppheader 中;
struct internal_data {};
template<typename T>
struct Internal {
T data;
};
template <typename T>
Opaque map_internal(Internal<T>* p)
{
return reinterpret_cast<Opaque>(p);
}
template <typename T>
Internal<T>* remap_internal(Opaque p)
{
return reinterpret_cast<Internal<T>*>(p);
}
然后内部Initialise
更改为;
template<typename T>
Opaque Initialise(T data) {
Internal<T>* t = new Internal<T>();
t->data = data;
return map_internal(t);
}
您没有提及有关资源管理的任何内容,但map_internal
的反面可用于在需要时将Opaque
转换回相应delete
的Internal<T>
。
注意:类型安全在这里是一个问题(w.r.t.reinterpret_cast
(,但在这种情况下,权衡是类型安全与互操作性。由于严格的别名,您不应尝试访问可能(将来(在internal_data
中的任何数据,它只是为了从Internal<T>
转换和转换回
这里值得注意的是cpp首选项,转换5,与C++规范5.2.10有关。
指向T1 类型的对象的任何指针都可以转换为指向另一种类型 cv T2 的对象的指针。这完全等同于
static_cast<cv T2*>(static_cast<cv void*>(expression))
.
现场样品
也许工会会有所帮助?
template<typename T>
union InternalExtend
{
Internal<T>* internal;
Opaque opaque;
};
template<typename T>
Opaque Initialise(T data) {
InternalExtend<T> ret;
ret.internal = new Internal<T>();
ret.internal->data = data;
return ret.opaque;
}
- 为什么 C++ 中的以下结构声明会导致退出 127?
- 在.cpp文件之间传递结构声明,而不使用全局头文件
- 结构声明中的 if 语句C++
- 这个嵌套结构声明是什么意思?
- 在结构声明的分号之前声明的结构变量是否为全局变量
- 为什么结构声明在C++中违反了 ODR
- 错误:多个文件中的结构声明冲突
- 为什么调用定义的构造函数会导致结构声明中出现错误,我该如何修复它
- C++数据结构声明
- 相互依赖的结构声明
- 结构声明的数组
- 结构声明中的":"是什么意思
- 面向C++的main.cpp中的可视化结构声明问题
- 当某些结构字段被省略或与结构声明中的顺序不同时,如何实现正确的解析?
- 编译器在转发结构声明上出错
- C++生成器 XE4 中的结构声明
- 我无法理解c ++中的结构声明
- 嵌套结构声明以及如何访问它们
- 将包含单个数组的结构声明为packed有什么缺点吗
- 定义之前的结构声明