[英]How to detect whether a class has no virtual base in C++17 at compile time?
鑒於:
如何在編譯時檢測T在C ++ 17中是否沒有虛基?
編輯:
我實際上是在寫一個類型擦除的容器,當我在編寫獲取復制ctor的代碼時,我發現只要一個類沒有虛擬基礎並且沒有用戶提供的復制ctor,復制ctor就可以成為指向諸如std :: memcpy之類的東西的指針。
為了找出是否可以使用std::memcpy
,實際上需要std::is_trivially_meowable
。
例如,如果要使用std::memcpy
復制,則可以使用std::is_trivially_copyable
進行檢查。
您還可以檢查可瑣碎的和可碎毀的。
正如您在評論中所說,您還想對非瑣碎的類進行此操作。 這不可避免地導致不確定的行為,所以我不會嘗試。 我建議刪除那些類中的vtable並使其變得瑣碎,然后再依賴未明確定義的行為。
另外,如果您使用指向這些類的指針,則指針本身是微不足道的。 因此,您可以通過這種方式輕松地復制您的課程。
你也許能夠,以確定這一點,如果你正在使用微軟的Visual C ++基於指針的大小,以類的成員函數。 它不適用於其他編譯器,尤其是實現Itanium C ++ ABI的那些編譯器。
隨着微軟的實現,一個類的布局可以根據虛基類的位置變化,以及指針到成員函數需要一個抵消施加得到正確的this
指針調用。 存在虛擬基類時,這會導致指向成員函數的指針比沒有虛擬基類時的更大。 由於sizeof
運算符是一個編譯時間常數,因此可以在各個地方(包括模板參數)使用它來基於虛擬庫的存在來區分代碼。
這是一個簡單的測試程序(在Godbolt上 )。 如果可以編譯,則可以使用成員函數指針的大小來確定是否為類指定了虛擬基類。
struct B {
void f();
};
struct C: virtual public B {
void g();
};
int test(int s) {
switch (s) {
case sizeof(&C::g):
return 1;
case sizeof(&B::f):
return 2;
}
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.