<small id='BxfWT'></small><noframes id='BxfWT'>

<legend id='BxfWT'><style id='BxfWT'><dir id='BxfWT'><q id='BxfWT'></q></dir></style></legend>

        <bdo id='BxfWT'></bdo><ul id='BxfWT'></ul>
      <i id='BxfWT'><tr id='BxfWT'><dt id='BxfWT'><q id='BxfWT'><span id='BxfWT'><b id='BxfWT'><form id='BxfWT'><ins id='BxfWT'></ins><ul id='BxfWT'></ul><sub id='BxfWT'></sub></form><legend id='BxfWT'></legend><bdo id='BxfWT'><pre id='BxfWT'><center id='BxfWT'></center></pre></bdo></b><th id='BxfWT'></th></span></q></dt></tr></i><div id='BxfWT'><tfoot id='BxfWT'></tfoot><dl id='BxfWT'><fieldset id='BxfWT'></fieldset></dl></div>
      1. <tfoot id='BxfWT'></tfoot>
      2. 从 boost multi_index 数组中移动元素

        时间:2023-07-20
        <i id='zUaxZ'><tr id='zUaxZ'><dt id='zUaxZ'><q id='zUaxZ'><span id='zUaxZ'><b id='zUaxZ'><form id='zUaxZ'><ins id='zUaxZ'></ins><ul id='zUaxZ'></ul><sub id='zUaxZ'></sub></form><legend id='zUaxZ'></legend><bdo id='zUaxZ'><pre id='zUaxZ'><center id='zUaxZ'></center></pre></bdo></b><th id='zUaxZ'></th></span></q></dt></tr></i><div id='zUaxZ'><tfoot id='zUaxZ'></tfoot><dl id='zUaxZ'><fieldset id='zUaxZ'></fieldset></dl></div>
            <legend id='zUaxZ'><style id='zUaxZ'><dir id='zUaxZ'><q id='zUaxZ'></q></dir></style></legend>

              <tbody id='zUaxZ'></tbody>
            • <tfoot id='zUaxZ'></tfoot>

                  <bdo id='zUaxZ'></bdo><ul id='zUaxZ'></ul>

                  <small id='zUaxZ'></small><noframes id='zUaxZ'>

                  本文介绍了从 boost multi_index 数组中移动元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  假设我有可移动且不可复制的对象,并且我有带有 random_access 索引的 boost 多索引数组.我需要将我的对象移出数组前端,但我找不到任何方法,这会给我在 文档.我只能看到 front() 给我常量引用和 pop_front() 擦除元素,但不返回任何内容.那么有没有办法将元素移出 boost 多索引?

                  Let's say I have movable and not copyable object and I have boost multi-index array with random_access index. I need to move my object out of array front, but I cannot find any method, that would give me rvalue/lvalue reference in documentation. I can only see front() which gives me constant reference and pop_front() which erases element, but does not return anything. So is there a way to move element out of boost multi-index?

                  推荐答案

                  添加到@sehe 的回答中,以下显示了如何在您的可移动类型不可构造的情况下修改代码:

                  Adding to @sehe's answer, the following shows how to modify the code in case your moveable type is not default constructible:

                  更改了代码以正确处理*extracted的破坏.
                  添加了带有 std::unique_ptr 的替代方案.
                  通过 sehe 添加了第二个选项.

                  Edited: changed code to properly deal with destruction of *extracted.
                  Edited: added alternative with std::unique_ptr.
                  Edited: added a second altrnative by sehe.

                  生活在 Coliru

                  #include <boost/multi_index_container.hpp>
                  #include <boost/multi_index/random_access_index.hpp>
                  #include <iostream>
                  #include <type_traits>
                  
                  struct moveonly {
                      int x;
                      moveonly(int x) noexcept : x(x) {}
                      moveonly(moveonly&& o) noexcept : x(o.x) { o = {-1}; }
                      moveonly& operator=(moveonly o) noexcept { using std::swap; swap(x, o.x); return *this; }
                  };
                  
                  static_assert(not std::is_copy_constructible<moveonly>{}, "moveonly");
                  
                  namespace bmi = boost::multi_index;
                  using Table   = bmi::multi_index_container<moveonly,
                      bmi::indexed_by<
                          bmi::random_access<bmi::tag<struct _ra> >
                      > >;
                  
                  template <typename Container>
                  void dump(std::ostream& os, Container const& c) { 
                      for (auto& r: c) os << r.x << " ";
                      os << "
                  ";
                  }
                  
                  moveonly pop_front(Table& table) {
                      std::aligned_storage<sizeof(moveonly), alignof(moveonly)>::type buffer;
                      moveonly* extracted = reinterpret_cast<moveonly*>(&buffer);
                  
                      auto it = table.begin();
                      if (it == table.end())
                          throw std::logic_error("pop_front");
                  
                      if (table.modify(it, [&](moveonly& v) { new (extracted) moveonly{std::move(v)}; })) {
                          table.erase(it);
                      }
                  
                      try {
                          moveonly ret = std::move(*extracted);
                          extracted->~moveonly();
                          return ret;
                      } catch(...) {
                          extracted->~moveonly();
                          throw;
                      }
                  }
                  
                  int main() {
                      Table table;
                  
                      table.push_back({1});
                      table.push_back({2});
                      table.push_back({3});
                  
                      dump(std::cout << "table before: ", table);
                  
                      std::cout << "Extracted: " << pop_front(table).x << "
                  ";
                  
                      dump(std::cout << "table after: ", table);
                  }
                  

                  同样的事情使用 std::unique_ptr 进行清理:

                  Same thing using std::unique_ptr for cleanup:

                  生活在 Coliru

                  #include <boost/multi_index_container.hpp>
                  #include <boost/multi_index/random_access_index.hpp>
                  #include <iostream>
                  #include <memory>
                  #include <type_traits>
                  
                  struct moveonly {
                      int x;
                      moveonly(int x) noexcept : x(x) {}
                      moveonly(moveonly&& o) noexcept : x(o.x) { o = {-1}; }
                      moveonly& operator=(moveonly o) noexcept { using std::swap; swap(x, o.x); return *this; }
                  };
                  
                  static_assert(not std::is_copy_constructible<moveonly>{}, "moveonly");
                  
                  namespace bmi = boost::multi_index;
                  using Table   = bmi::multi_index_container<moveonly,
                      bmi::indexed_by<
                          bmi::random_access<bmi::tag<struct _ra> >
                      > >;
                  
                  template <typename Container>
                  void dump(std::ostream& os, Container const& c) { 
                      for (auto& r: c) os << r.x << " ";
                      os << "
                  ";
                  }
                  
                  moveonly pop_front(Table& table) {
                      std::aligned_storage<sizeof(moveonly), alignof(moveonly)>::type buffer;
                      moveonly* extracted = reinterpret_cast<moveonly*>(&buffer);
                  
                      auto it = table.begin();
                      if (it == table.end())
                          throw std::logic_error("pop_front");
                  
                      if (table.modify(it, [&](moveonly& v) { new (extracted) moveonly{std::move(v)}; })) {
                          table.erase(it);
                      }
                  
                      std::unique_ptr<moveonly,void(*)(moveonly*)> ptr = {
                          extracted,
                          [](moveonly* p){ p->~moveonly(); }
                      };
                  
                      return std::move(*extracted);
                  }
                  
                  int main() {
                      Table table;
                  
                      table.push_back({1});
                      table.push_back({2});
                      table.push_back({3});
                  
                      dump(std::cout << "table before: ", table);
                  
                      std::cout << "Extracted: " << pop_front(table).x << "
                  ";
                  
                      dump(std::cout << "table after: ", table);
                  }
                  

                  Sehe 提供了另一种基于 boost::optional 的替代方案,这是最优雅的总而言之:

                  Sehe provides yet another alternative based on boost::optional which is the most elegant of all:

                  生活在 Coliru

                  #include <boost/multi_index_container.hpp>
                  #include <boost/optional.hpp>
                  #include <boost/multi_index/random_access_index.hpp>
                  #include <iostream>
                  #include <memory>
                  #include <type_traits>
                  
                  struct moveonly {
                      int x;
                      moveonly(int x) noexcept : x(x) {}
                      moveonly(moveonly&& o) noexcept : x(o.x) { o = {-1}; }
                      moveonly& operator=(moveonly o) noexcept { using std::swap; swap(x, o.x); return *this; }
                  };
                  
                  static_assert(not std::is_copy_constructible<moveonly>{}, "moveonly");
                  
                  namespace bmi = boost::multi_index;
                  using Table   = bmi::multi_index_container<moveonly,
                      bmi::indexed_by<
                          bmi::random_access<bmi::tag<struct _ra> >
                      > >;
                  
                  template <typename Container>
                  void dump(std::ostream& os, Container const& c) { 
                      for (auto& r: c) os << r.x << " ";
                      os << "
                  ";
                  }
                  
                  moveonly pop_front(Table& table) {
                      boost::optional<moveonly> extracted;
                  
                      auto it = table.begin();
                      if (it == table.end())
                          throw std::logic_error("pop_front");
                  
                      if (table.modify(it, [&](moveonly& v) { extracted = std::move(v); })) {
                          table.erase(it);
                      }
                  
                      return std::move(*extracted);
                  }
                  
                  int main() {
                      Table table;
                  
                      table.push_back({1});
                      table.push_back({2});
                      table.push_back({3});
                  
                      dump(std::cout << "table before: ", table);
                  
                      std::cout << "Extracted: " << pop_front(table).x << "
                  ";
                  
                      dump(std::cout << "table after: ", table);
                  }
                  

                  这篇关于从 boost multi_index 数组中移动元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  <legend id='JrGak'><style id='JrGak'><dir id='JrGak'><q id='JrGak'></q></dir></style></legend>
                • <i id='JrGak'><tr id='JrGak'><dt id='JrGak'><q id='JrGak'><span id='JrGak'><b id='JrGak'><form id='JrGak'><ins id='JrGak'></ins><ul id='JrGak'></ul><sub id='JrGak'></sub></form><legend id='JrGak'></legend><bdo id='JrGak'><pre id='JrGak'><center id='JrGak'></center></pre></bdo></b><th id='JrGak'></th></span></q></dt></tr></i><div id='JrGak'><tfoot id='JrGak'></tfoot><dl id='JrGak'><fieldset id='JrGak'></fieldset></dl></div>

                    • <tfoot id='JrGak'></tfoot>
                        <tbody id='JrGak'></tbody>

                      <small id='JrGak'></small><noframes id='JrGak'>

                          • <bdo id='JrGak'></bdo><ul id='JrGak'></ul>