[英]What does `class template Example<int>;` statement mean with C++11?
[英]What does “return {}” statement mean in C++11?
這句話是什么?
return {};
在C ++ 11中指出,何時使用它而不是(比如說)
return NULL;
要么
return nullptr;
return {};
表示“返回使用空list-initializer初始化的函數返回類型的對象”。 確切的行為取決於返回的對象的類型。
來自cppreference.com (因為OP標記為C ++ 11,我排除了C ++ 14和C ++ 17中的規則;請參閱該鏈接以獲取更多詳細信息):
- 如果braced-init-list為空且T是具有默認構造函數的類類型,則執行值初始化。
- 否則,如果T是聚合類型,則執行聚合初始化。
- 否則,如果T是std :: initializer_list的特化,則根據上下文,從braced-init-list直接初始化或復制初始化T對象。
否則,T的構造函數分為兩個階段:
- 將std :: initializer_list作為唯一參數的所有構造函數,或作為第一個參數,如果其余參數具有默認值,將檢查所有構造函數,並通過重載決策與std :: initializer_list類型的單個參數進行匹配
- 如果前一個階段沒有產生匹配,則T的所有構造函數都參與對由braced-init-list元素組成的參數集的重載解析,並限制只允許非縮小轉換。 如果此階段產生顯式構造函數作為復制列表初始化的最佳匹配,則編譯失敗(注意,在簡單的復制初始化中,根本不考慮顯式構造函數)。
否則(如果T不是類類型),如果braced-init-list只有一個元素,並且T不是引用類型或者是與元素類型兼容的引用類型,則T是直接的 - 初始化(在直接列表初始化中)或復制初始化(在復制列表初始化中),但不允許縮小轉換。
- 否則,如果T是與元素類型不兼容的引用類型。 (如果引用是非常量左值引用,則會失敗)
- 否則,如果braced-init-list沒有元素,則T是值初始化的。
在C ++ 11之前,對於返回std::string
的函數,你會寫:
std::string get_string() {
return std::string();
}
使用C ++ 11中的大括號語法,您不需要重復類型:
std::string get_string() {
return {}; // an empty string is returned
}
當函數返回指針類型時,應該使用return NULL
並return nullptr
:
any_type* get_pointer() {
return nullptr;
}
但是,自C ++ 11以來不推薦使用NULL
因為它只是整數值(0)的別名,而nullptr
是一個真正的指針類型:
int get_int() {
return NULL; // will compile, NULL is an integer
}
int get_int() {
return nullptr; // error: nullptr is not an integer
}
這可能令人困惑:
int foo()
{
return {}; // honestly, just return 0 - it's clearer
}
這可能不是:
SomeObjectWithADefaultConstructor foo()
{
return {};
// equivalent to return SomeObjectWithADefaultConstructor {};
}
return {};
表示{}
是返回值的初始值設定項 。 返回值使用空列表進行列表初始化。
以下是基於C ++標准中[stmt.return]的返回值的一些背景知識:
對於按值返回的函數(即返回類型不是引用而不是void
),有一個名為返回值的臨時對象。 此對象由return
語句創建,其初始值設定項取決於return語句中的內容。
返回值一直存在,直到調用該函數的代碼中的完整表達式結束; 如果它有類類型,那么它的析構函數將運行,除非它的生命周期延長了調用者直接將引用綁定到它。
返回值可以通過兩種不同的方式初始化:
return some_expression;
- 返回值是從some_expression
復制初始化的 return { possibly_empty_list };
- 返回值從列表中進行列表初始化 。 假設T
是函數的返回類型,則注意return T{};
與return {}
不同:在前者中,創建臨時T{}
,然后從該臨時值復制初始化返回值 。
如果T
沒有可訪問的copy / move-constructor,則無法編譯,但return {};
即使那些構造函數不存在,也會成功。 因此, return T{};
可能會顯示復制構造函數等的副作用,雖然這是復制省略,因此可能不會。
下面簡要回顧一下C ++ 14中的列表初始化 (N4140 [dcl.init.list] / 3),其中初始化器是一個空列表:
T
是一個聚合,那么每個成員都是從它的大括號或初始化器中初始化的,如果它有一個,否則好像是{}
(所以遞歸地應用這些步驟)。 T
是具有用戶提供的默認構造函數的類類型,則調用該構造函數。 T
是具有隱式定義的或= default
ed默認構造函數的類類型,則對象將進行零初始化 ,然后調用默認構造函數。 T
是std::initializer_list
,則返回值為空這樣的列表。 T
是非類型 - 返回類型不能是數組),返回值為零初始化。 這是方法返回類型的新實例的一種簡寫。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.