2015-08-28 144 views
7

我有下面的代碼,它不會編譯,它是星期五,我有點疲憊。C++ std :: unique_ptr存儲在std :: map中使用刪除函數生成

#include <string> 
#include <memory> 
#include <utility> 
#include <map> 

template< typename T, typename ...Args > 
std::unique_ptr<T> make_unique(Args && ...args) 
{ 
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); 
} 

struct A 
{ 
}; 

std::map< std::string, std::unique_ptr<A> > _map = { { "A", make_unique<A>() } }; // <-- ERROR!! 

以下編譯沒有問題

int main() 
{ 
    std::pair< std::string, std::unique_ptr<A> > p { "B", make_unique<A>() }; 
    _map.insert(std::make_pair("C", make_unique<A>())); 
} 

我得到的錯誤是(粗略地除去克++絨毛)

use of deleted function 'constexpr std::pair<...>(const st::pair<...> &) 
'constexp std::pair<...>::pair(const std::pair<...> &) is implicitly deleted because the default definition would be illegal. 

Argghh !! 只需在C++ 11標準中閱讀。

當集合由初始化列表初始化,如在8.5.4指定 ,初始化器列表的元素被作爲 初始化爲聚集體的成員,在增加下標 或部件的順序。每個成員是副本初始化對應初始化子句

長號從 !!!

任何人都知道,如果這是簡單的不可能與初始化列表?

+0

我真的需要這個來與初始化列表一起工作。編譯的代碼就是例子。 – ScaryAardvark

+0

嗯。就是想。初始化列表是否要求它們的參數是可複製的?在這種情況下,錯誤是有道理的,因爲你不能複製一個unique_ptr – ScaryAardvark

+3

[This](http://stackoverflow.com/questions/8193102/initializer-list-and-move-semantics)似乎相關.... –

回答

5

你不能做太多的事情:複製初始化列表中的元素。這不會與只移動的類相處。

有一種方法可以繞過這個「缺陷」,但它不是很好看;你決定

using map_type = std::map< std::string, std::unique_ptr<A> >; 
using pair_type = map_type::value_type; 
pair_type elements[] = { { "A", std::make_unique<A>() }, { "B", std::make_unique<A>() } }; 

map_type myMap { std::make_move_iterator(begin(elements)), std::make_move_iterator(end(elements)) }; 

這將使myMap遍歷範圍內移動的元素,而不是複製。方法善意取自this其他問題。

+0

這是一個很好的解決方法,但它就像你說的那樣不好。然而,因爲它解決了我目前遇到的問題,所以你得到了金星:o) – ScaryAardvark

相關問題