簡體   English   中英

非平凡可復制類型的C ++值表示

[英]C++ value representation of non-trivially-copyable types

目前的C ++標准草案(2019年3月)有以下段落([basic.types] p.4)(強調我的):

類型T的對象的對象表示是由類型T的對象占據的N個無符號字符對象的序列,其中N等於sizeof(T)。 類型T的對象的值表示是參與表示類型T的值的比特集。對象表示中不是值表示的一部分的比特是填充比特。 對於簡單的可復制類型,值表示是對象表示中的一組位,用於確定值,該值是實現定義的值集的一個離散元素

為什么突出顯示的句子僅限於易於復制的類型? 是因為來自非平凡可復制對象的值表示的某些位可能在其對象表示之外嗎? 這個答案 ,以及這一點暗示了這一點。

但是,在上面鏈接的答案中,對象的概念基於用戶引入的語義。 在第一個鏈接答案的示例中:

class some_other_type
{
    int a;
    std::string s;
};

用戶確定some_other_type類型的對象的包括屬於字符串s的字符。

我試着想一個例子,其中一個對象的某些部分(不是簡單的可復制值表示在其對象表示之外是隱式的(實現必須這樣做,它不是由用戶任意決定的)。

我想到的一個例子是,具有虛方法的基類子對象的值表示可能包括來自它所屬的完整對象的對象表示的位,因為基類子對象可能表現不同(可能“有”一個不同的值“)與它本身就是一個完整的對象的情況相比。

我的另一個例子是vtable也可能是vtable指針指向它的對象的值表示的一部分。

這些例子是否正確? 還有其他例子嗎?

標准委員會是否引入了突出顯示的句子,因為對象的語義“價值”可能由用戶決定(如在兩個鏈接的答案中),或者因為實現可能決定(或可能是強迫)這樣做,還是兩者兼而有之?

謝謝。

在我的解釋中,你強調的句子的重點是這一部分:

對於簡單的可復制類型,值表示是對象表示中的一組位用於確定值,該值是實現定義的值集的一個離散元素。

本質上,標准的[basic.types]#4表示“每個對象都有一組作為其對象表示的位O和一組作為其值表示VP = O without V的集合P = O without V是填充位對於簡單的可復制類型, VO的子集 后者很重要,因為它意味着圍繞O組位復制也可以安全地復制V用於簡單的可復制類型,因此保留了該值。 如何為其他類型定義V在這里無關緊要(如果需要,可將其設置為整個抽象機)。


要回答評論中提到的修訂問題:

為什么一個實現不能告訴1110000100010001111是否意味着它是否是一個非平凡可復制對象的對象表示? 是因為還有一些其他位(在此對象表示之外)有助於確定對象具有什么值?

我們以std::string為例。 它不是易於復制的,因為它必須處理內存管理。

如果兩個std::string對象具有相同的位模式,它們是否意味着相同的東西?

沒有。至少有一個實現通過讓緩沖區指針指向自身(gcc)來指示小字符串優化。 在銷毀時,如果(並且僅當)它沒有指向該確切位置,則釋放緩沖區。

顯然,駐留在不同位置的兩個std::string對象必須(在此實現中)表示具有不同位模式的相同(小)字符串值(緩沖區指針必須不同)。 更重要的是,兩個對象中相同的位模式可能意味着非常不同的東西 - 它可能表示一個案例中的SSO而不是另一個案例中的SSO。

正如你所看到的,有參與每個值表示附加信息std::string這里:它在內存中的位置(也就是值this )。 標准沒有進一步說明用比特表示的具體情況。

暫無
暫無

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

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