2016-05-26 8 views
1

佈設我不知道如果我理解正確的驗證碼地圖動與左值

template<typename M> 
void add(M& m,int i, std::string s) 
{ 
    m.emplace(i,std::move(s)); 
} 

int main() 
{ 
    std::map<int,std::string> m; 
    add(m,1,"foo"); 
} 

add被調用時,std::stringint被複制。方法emplace構造一個std::pair它被移動到std::map(不需要複製)。但是int的副本是一個左值,而std::string的副本被轉換爲右值,因此調用哪個構造函數來構造std::pair?由於一個論點不能被移動,我想在這裏有一個額外的副本。這樣對嗎?很明顯,如果我還將int的副本也投給了右值,我預計不會有額外的副本。

回答

4

這個構造函數被調用:

template< class U1, class U2 > 
pair(U1&& x, U2&& y); 

在這種情況下xy不是右值引用,但普遍引用。長話短說,由於你的std::move(),左值(在本例中爲int)摺疊爲左值參考和右值(在這種情況下爲std::string)爲右值參考。

實例化的構造是這樣的:

pair(int& x, std::string&& y); 

斯科特邁爾斯解釋它更好https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers

+0

所以'std :: pair'構造了複製'int'並移動了'std :: string'的權利? –

+0

@MarcoAgnese正確 – imreal

0

add被調用時,std::stringint被複制。

int被複制,但沒有初始std::string複製。相反,s構建就地在功能本身從字符串字面量要傳遞的。

因此

其構造函數構造std::pair

我們可以混合和匹配。有一個轉發參考構造模板std::pair

template< class U1, class U2 > 
pair(U1&& x, U2&& y);   // since C++11, until C++14 

template< class U1, class U2 > 
constexpr pair(U1&& x, U2&& y); // since C++14 

所以在這種情況下,我們稱之爲pair<int&, std::string>。沒有「額外的副本」。