2014-12-27 62 views
4

我正在使用STL關聯容器(std::setstd::map)以及包含std::unique_ptr<>實例的鍵。主要定義等效於以下:STL關聯容器:清除並獲取(不可複製)元素

struct Key 
{ 
    std::unique_ptr<Object> object; 
    bool operator== (const Key& rhs) const { return object->equal (*rhs.object); } 
    bool operator< (const Key& rhs) const { return object->less (*rhs.object); } 
} 

已知STL關聯容器(尤其因爲C++ 11。)不具有一種方式來獲得非const參照從移動鍵。而且我的密鑰是不可複製的,所以c++: Remove element from container and get it back不起作用。

有沒有非UB的方法來克服這個問題?

我目前的解決方案是以下幾點:

template <typename T> 
using map_pair_type = std::pair<typename T::key_type, typename T::mapped_type>; 

template <typename T> 
typename T::value_type take_set (T& container, typename T::iterator iterator) 
{ 
    typename T::value_type result = std::move (const_cast<typename T::value_type&> (*iterator)); 
    container.erase (iterator); 
    return result; 
} 

template <typename T> 
map_pair_type<T> take_map (T& container, typename T::iterator iterator) 
{ 
    map_pair_type<T> result { 
     std::move (const_cast<typename T::key_type&> (iterator->first)), 
     std::move (iterator->second) 
    }; 
    container.erase (iterator); 
    return result; 
} 
+3

_「是否有非UB方式來解決這個問題?」_編號[N3645](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3645 .pdf)可能會有所幫助,但該提案已被拒絕,並且未被再次提交。 – 2014-12-27 21:09:54

回答

6

這就是其中之一:

實在不好意思。我們試圖做這個工作,並不能通過 委員會。

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3586.pdf

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3645.pdf

你的解決方案是盡善盡美,據我所知。您的地圖解決方案會顯示未定義的行爲。如果第二次移動拋出異常,它會變得非常糟糕。除此之外,我懷疑它會起作用。我懷疑我會因此而投票贊成。

UB的原因是密鑰被定義爲const(與僅由const引用引用相反)。在這種情況下拋棄const(並且有一個移動構造函數修改對象)是UB。

只好N3586被接受,你可以只:

move_only_type mot = move(*s.remove(s.begin())); 

或:

move_only_key mok = move(m.remove(m.begin())->first); 

N3586/N3645在委員會取得了良好的表現。討論並通過工作小組討論,只是在全委會中被擊落。關心的是,std :: lib將不得不提交UB才能實現它。它沒有被重新提交。

+0

感謝您的回答。 如果我設法做一些異常安全*(RAII式迭代器「橡皮擦」可能?)*,它會保持UB嗎? – intelfx 2014-12-27 21:22:51

+0

還有一個後續問題。該提案(後者)的地位如何?被拒絕,還是未被審查,或被拒絕並將被重新提交?.. – intelfx 2014-12-27 21:25:37

+1

將'const'拋出去並不是UB。試圖修改一個'const'對象是UB。 – Columbo 2014-12-27 21:41:14