簡體   English   中英

如何將非可復制類的默認構造對象放入boost :: container :: map中?

[英]How can a default-constructed object of a non-copyable class be emplaced into a boost::container::map?

考慮下面的C ++ 03代碼(我必須使代碼與pre-C ++ 11編譯器兼容):

// This class belongs to a third-party SDK and cannot be touched
class A {
public:
    explicit A();
    explicit A(bool b);
private:
    // Non-copyable
    A(const A&);
    const A& operator= (const A&);
}

boost::container::map<int, A> myMap;

在這里使用Boost地圖,因為即使在C ++ 03中它也允許放置。 問題是,如果使用單參數構造函數,我可以在地圖中完成emplace-construct,但我不知道如何默認構造對象,如下代碼所示:

myMap.emplace(1, true); // Works
myMap.emplace(1);       // Fails

第二次調用失敗,因為它被視為對emplace(std :: pair ...)重載的調用,所以似乎沒有辦法“default-emplace”。

有沒有辦法實現我想要的?

通過使A可移動但不可復制,然后將對象移動到安置功能。

在C ++ 03中,您可以使用Boost.Move使A可移動。 例:

#include <boost/container/map.hpp>
#include <boost/move/move.hpp>
#include <cassert>

class A { 
    BOOST_MOVABLE_BUT_NOT_COPYABLE(A)
public:
    explicit A() {}; 
    explicit A(bool b) {}; 
    A(BOOST_RV_REF(A)) {}
    A& operator=(BOOST_RV_REF(A)) { return * this; }

private:
    // Non-copyable
//    A(const A&);
//    const A& operator= (const A&);
};


int main()
{
    boost::container::map<int, A> myMap;
    myMap.emplace(1, true); // Works

    A a;
    myMap.emplace(1, boost::move (a));
//  myMap.emplace(1);       // Fails

}

出於興趣,我玩了這個

作為一個重要的數據點,我知道std::map (在C ++ 11中)支持它的值對的分段構造

std::map<int, A> stdMap;
stdMap.emplace(std::piecewise_construct, 
     std::forward_as_tuple(1), 
     std::forward_as_tuple());

因此會調用你所追求的構造函數。 然而,不知何故,同樣不會立即為Boost的map 嗯。

然而,這引起了我的興趣:boost使用std::pair<const K, V>作為值類型?!

boost::container::map<int, A>::value_type p { 
       std::piecewise_construct, 
       std::forward_as_tuple(1), 
       std::forward_as_tuple(true) 
};

沒問題。 我還可以驗證此typedef 實際上是存儲的類型:

static_assert(std::is_same<decltype(p), std::remove_reference<decltype(*myMap.begin())>::type>::value, "Nonstandard pair");

因此,當它使用allocator::construct調用時,它開始看起來像是通過內部樹實現轉發的錯誤。

最近為Boost 1.62添加了piecewise_construct支持。 所以下面的代碼:

#include <boost/container/map.hpp>
#include <boost/tuple/tuple.hpp>

// This class belongs to a third-party SDK and cannot be touched
class A
{
   public:
   explicit A(){}
   explicit A(bool b);

   private:
   // Non-copyable
   A(const A&);
   const A& operator= (const A&);
};

int main()
{
   using namespace boost::container;
   map<int, A> myMap;

   myMap.emplace(piecewise_construct, boost::tuple<int>(1), boost::tuple<>());

   return 0;
}

應該在C ++ 03和C ++ 11 +編譯器中工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM