簡體   English   中英

直接重置結構的內容

[英]Reset directly the content of a struct

我已經實現了一個 function 來重置指針指向的結構的內容:

template <typename Struct>
void initialize(Struct* s)
{
    *s = Struct{};
}

Struct變大(超過 10K)時,我會遇到性能問題,因為Struct是在堆棧中創建的,然后分配給*s 我想知道我是否可以改進它:

  1. 是否可以在沒有臨時Struct{} object 的情況下直接初始化*s
  2. 我是否應該評估Struct的大小並將其構建在堆中(如果它很大)?

先感謝您

首先,您可能應該使用參考; 不是指針。 這樣做的目的是避免 null 間接錯誤。

如果 class 是平凡的並且值初始化為零(這通常是大多數平凡類型的情況),那么優化器應該將您的 function 編譯為對memset的調用,而無需初始化臨時 ZA668CFDE691ACZF456。 所以在這種情況下應該沒有理由擔心。

您可以顯式調用memset ,盡管從技術上講,如果 class 包含某些類型(例如,null 指針不一定具有零表示),這在技術上不能移植到外來系統。

是否可以在沒有臨時 Struct{} object 的情況下直接初始化 *s?

是的,如果您願意更改 function 的要求。 目前它適用於默認可構造和可移動分配的類。

如果直接修改指向的 object,則可以避免創建臨時 object。 在以下示例中,沒有創建Struct類型的臨時對象:

constexpr void
initialize(Struct& s)
{
    s.member1 = T1{};
    s.member2 = T2{};

為了使其通用,可以在成員 function 中執行操作。 因此,您可以指定一個要求,即指向的 class 具有一個具有特定名稱且沒有參數的成員 function:

s.clear();

您可以將這兩種方法組合用於它們適用的類型:

template<class Struct>
constexpr void
initialize(Struct& s)
{
    if constexpr (std::is_trivially_copyable_v<Struct>) {
        // alternative 1, if you trust your optimiser
        s = Struct{};
        // alternative 2, if you doubt the quality of the optimiser
        //    technically may have different meaning on exotic systems
        std::memset(&s, 0, sizeof s);
    } else {
        s.clear();
    }
}

如果您需要它來處理一些不符合這兩個要求的類,那么您需要專門化模板。

我是否應該評估 Struct 的大小並將其構建在堆中(如果它很大 [10K])?

您通常應該避免完全擁有這么大的公共課程。 如果您需要如此大的存儲空間,您可以將其包裝在動態分配的類型中。 像這樣的東西:

class Struct
{
private:
    struct VeryLarge{/.../};
    std::unique_ptr<VeryLarge> storage;
public:
    // public interface

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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