[英]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> {};
但都沒有編譯。
據我所知,這看起來是C到C ++的典型代表,反之亦然。
鑒於您無法更改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
投射回Internal<T>
進行相應的delete
。
注意:這里需要考慮類型安全性(將reinterpret_cast
),但是在這種情況下,需要權衡的是類型安全性與互操作性。 由於嚴格別名,你不應該試圖訪問可能(在未來)是任何數據internal_data
,它的存在只是為了從轉換和回Internal<T>
此處值得注意的是cppreference ,轉換5,與C ++規范5.2.10相關。
指向類型T1的對象的任何指針都可以轉換為指向另一類型cv T2的對象的指針。 這完全等同於
static_cast<cv T2*>(static_cast<cv void*>(expression))
如果您不想reinterpret_cast<>
,則可以從虛擬internal_data
繼承,即
struct internal_data {};
template<typename T>
struct Internal: internal_data {
T data;
};
當您需要訪問數據時,只需將指針向下轉換到模板類型即可。
工會會有所幫助嗎?
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.