簡體   English   中英

顯式默認默認構造函數和聚合

[英]Explicit defaulted default constructor and aggregates

當我編譯以下代碼的#if 0#if 1版本時,如何解釋差異:

#include <cstdlib>

struct A
{ 
    explicit A() = default; // explicitly defaulted or deleted constructors are allowed for aggregates (since C++11)
#if 1
private :
#endif
    int i;
};

int
main()
{
    A a = {};
    return EXIT_SUCCESS;
}
  • 對於#if 0一切都很好,編譯成功。
  • for #if 1編譯失敗,錯誤消息:

    錯誤:選擇的構造函數在復制初始化中是顯式的

表達式A a = {};什么區別A a = {}; 取決於A是否是萬能?

TL; DR:Clang和GCC拒絕您的代碼是錯誤的。 無論選擇的默認構造函數是否explicit CWG 1630的分辨率都使得默認初始化格式良好。


i private代碼的變體中, A不是聚合,因為它們不能擁有私有成員。 但是,只要ipublicA就是聚合1 ,並且由於執行了聚合初始化而沒有調用構造函數(參見藍框),所以你的構造函數是explicit是無關緊要的。

在此輸入圖像描述

但是,只要您引入私有成員,就需要根據紅色框進行值初始化。 因此[dcl.init] /(8.2)適用:

在此輸入圖像描述

[dcl.init] /(7.1)定義了這種情況的默認初始化:

在此輸入圖像描述

並且§13.3.1.3給出

對於默認初始化,候選函數是正在初始化的對象的類的所有構造函數。

在任何時候都不考慮原始上下文 - 復制或直接初始化。 (§13.3.1.7也不適用。)事實上,這是有意的; CWG#1518

問題1630的解決方案解決了這個問題默認初始化現在使用13.3.1.3 [over.match.ctor],現在允許顯式構造函數進行默認初始化。

Clang和GCC(以及VC ++)尚未實現相應的DR,因此在拒絕C ++ 14模式中的代碼時是不正確的。


1)您的類具有用戶聲明的構造函數,但它不是用戶提供的 ,即不會阻止您的類成為聚合。 回想一下[dcl.init.aggr] / 1中的定義:

聚合是一個數組或類(第9條),沒有用戶提供的構造函數(12.1),沒有私有或受保護的非靜態數據成員(第11條),沒有基類(第10條),沒有虛函數(10.3) )。

暫無
暫無

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

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