簡體   English   中英

如何在編譯時檢測C ++ 17中的類是否沒有虛擬基礎?

[英]How to detect whether a class has no virtual base in C++17 at compile time?

鑒於:

  1. 定義的類型T;
  2. 您想要的任何工具。

如何在編譯時檢測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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM