2012-12-19 38 views
5

可能重複:
initializer_list and move semantics移動初始化程序列表的元素是否安全?

在此代碼:

#include <vector> 
#include <initializer_list> 

template<typename T> 
class some_custom_container : public std::vector<T> 
{ 
public: 
    some_custom_container(const std::initializer_list<T>& contents) 
    { 
     for (auto& i : contents) 
     this->emplace_back(std::move(i)); 
    } 
}; 

class test_class 
{}; 

int main() 
{ 
    test_class a; 

    some_custom_container<test_class> i = { a, test_class(), a }; 
} 

如果我的理解是,在{ a, test_class(), a }所有對象都是安全構建的:在named-複製對象並移動未命名的對象以構造initializer_list。之後,initializer_list通過引用some_custom_container的構造函數傳遞。

然後,爲了避免無用的doble-copies,我將它們全部移動以填充矢量。

這個構造函數是否安全?我的意思是,在一個奇怪的情況下,例如,如果T被評估爲參考&或& &,是矢量總是充分填充(包含它的安全對象)?

如果是這種情況,爲什麼stl容器的構造函數實現沒有以這種方式實現?據我所知,他們的建設者複製並不會移動內容。

+0

它甚至沒有編譯,因爲初始值設定項列表只提供對其內容的const訪問,並且不能從引用移動到const。另請參閱:http://stackoverflow.com/questions/8468774/can-i-list-initialize-a-vector-of-move-only-type –

+2

這不會阻止它編譯,只能移動。複製構造函數將被調用。 – Puppy

回答

4

initializer_list只提供const訪問其元素。你可以使用const_cast來編譯代碼,但是這樣做可能會導致未定義的行爲(如果initializer_list的元素是真正的const)。所以,不這樣做並不安全。有are workarounds for this,如果你真的需要它。

+0

考慮在cpptruths上描述的成語(http://cpptruths.blogspot.com/2013/09/21-ways-of-passing-parameters-plus-one.html)。這個想法是在運行時確定左值/右值,然後調用移動或複製構造。即使由initializer_list提供的標準接口是const引用,在中也會檢測右值/左值。 – Sumant

+0

@Sumant這種庸俗的混亂是否實際上爲性能或內存使用提供了任何可衡量的好處,如果是這樣,這些好處足以抵消它看起來有多糟糕,並且需要大約一個小時才能弄清楚它是什麼試圖做什麼?我有點懷疑它。 –

相關問題