2016-06-09 35 views
-1

[現代有效的C++]說:爲什麼「auto」在推導返回值時無法接受braced-init-list?

template<class T> 
void f(T t){} 
int main(){ 
    f({1,2,3}); 
} 

將失敗的編譯,因爲當模板實例,T的類型必須是已知的,而在這裏{1,2,3}的支撐,初始化列表。應該解決,如:

auto x={1,2,3};//auto deduces x to std::initializer_list 
f(x); 

我能理解這一點,但後來我的問題:

爲什麼這本書繼續說,使用「自動」的返回值扣除時,它不能接受並推斷支撐-INIT -list?

auto f() 
{ 
    return {1,2,3}; 
} 

將無法​​編譯。

Emmmmm,如果這是C++ 14標準的一部分,我不明白爲什麼有這樣的限制,並且它繼續說:

auto resetV=[&v](const auto& newValue){v=new Value;} 

「自動」,「NEWVALUE」之前不能接受{1,2,3}。爲什麼我們有這樣的2個限制?

我想也許從語言設計的角度來看,做類型演繹時會有些混亂嗎?只是一個猜測。 這些設計決定的任何線索?它讓我困惑了好幾天。

謝謝。

回答

2

std::initializer_list是對匿名數組的引用。

陣列本身位於創建initializer_list的塊範圍。

std::initializer_list<int> f() { 
    return {1,2,3}; 
} 

是幾乎完全沒用,因爲陣列的壽命是f身體,並且指的是它存在於一個代碼幾乎完全不相交期間initializer_list

使用initializer_list幾乎肯定會是未定義的行爲。你可能會問它的大小,如果它是空的,這可能是定義的行爲(不知道,不關心檢查),但你絕對不能檢查它的內容。

初始化程序列表是對數據的引用,而不是數據的副本。

如果:

auto f() { 
    return {1,2,3}; 
} 

推斷自己是上面的,這將是幾乎不會有用。

auto x = {1,2,3};起作用的例外是其中initailizer_list<int>可以從一組{}推導出的唯一情況。 (在C++ 11中,auto x{1};也是如此,但是被刪除了)。

1

爲什麼本書繼續說,當使用「auto」進行返回值扣除時,它不能接受和推斷braced-init-list?

這並不是說它「不能推論出來」。這是不允許的。仔細想想這個代碼:

#include <initializer_list> 

auto f() -> std::initializer_list<int> 
{ 
    return {1,2,3}; 
} 

它會編譯嗎?是。它安全嗎?不可以。這可能會在底層數組的生命週期中引入各種問題。不應該像容器一樣使用std::initializer_list

+0

不只是「潛在」。只要離開函數,該數組就是一個ex數組。 –

+0

返回類型是initializer_list對象的副本,爲什麼它是一個ex數組?謝謝 –

相關問題