【问题标题】:Boost Intrusive Swap增强侵入式交换
【发布时间】:2013-12-17 20:57:25
【问题描述】:

我有一个声明为class MyClass : public list_base_hook<link_mode<normal_link>> 的类。我还有一个声明为 list<MyClass> global_list_MyClass 的列表。

我使用 for 循环将 10 个节点插入 global_list_MyClass。我的目标是尝试使用boost::intrusive::swap 交换Node1Node2,但似乎失败了(很多编译错误)。

我试图在互联网上搜索,但找不到任何好的例子。

示例代码:

class MyClass : public list_base_hook<link_mode<normal_link>>
{
public:
   int nValue;

public:
    MyClass(){}
    virtual ~MyClass(){}
};
static boost::intrusive::list<MyClass> global_list_MyClass;


//Insert 10 nodes
for (int n=0; n<10; n++)
{
  MyClass *p_oTMP1 = new MyClass();
  p_oTMP1->nValue = n;
  global_list_MyClass.push_back(*p_oTMP1);
}


//Search for Target node 1
int nTarget1 = 5;
boost::intrusive::list<MyClass>::iterator oTmpTarget1;
for (list<MyClass>::iterator iTmpToken=global_list_MyClass.begin();     iTmpToken!=global_list_MyClass.end(); iTmpToken++)
{
  if (!(iTmpToken->nValue == nTarget1))
    continue;
  oTmpTarget1 = iTmpToken;
  break;
}


//Search for Target node 2
int nTarget2 = 6;
boost::intrusive::list<MyClass>::iterator oTmpTarget2;
for (list<MyClass>::iterator iTmpToken=global_list_MyClass.begin(); iTmpToken!=global_list_MyClass.end(); iTmpToken++)
{
  if (!(iTmpToken->nValue == nTarget2))
    continue;
  oTmpTarget2 = iTmpToken;
  break;
}


//Swap Node1 with Node2
/*Here is what i not sure what to do with boost::intrusive::swap or     global_list_MyClass.swap()

【问题讨论】:

  • 显示你的编译错误。我们无法修复我们看不到的东西。
  • 抱歉,我的水晶球现在坏了。您必须向我们提供更多信息 - 例如最小的代码示例(或者更好的是 SSCCE),以及编译错误。
  • 不要再次感谢这个问题,Angew 删除了它们,因为它们只是噪音。
  • 至于“谢谢”,是a site policy(另见here)。
  • 好的,抱歉,这是我在 stackoverflow.com 上的第一篇文章

标签: c++ boost intrusive-containers boost-intrusive


【解决方案1】:

我认为您不能在这里使用swap() - 那是用于交换容器,而不是容器内的节点。不过,您可以删除元素并将它们重新插入到交换的位置:

void swapItems(boost::intrusive::list<MyClass> &list, boost::intrusive::list<MyClass>::iterator it1, boost::intrusive::list<MyClass>::iterator it2)
{
  if (it1 == it2) return;
  MyClass &node1 = *it1;
  MyClass &node2 = *it2;
  it1 = list.erase(it1);
  if (it1 == it2) {  //1 was immediately followed by 2
    list.insert(++it2, node1);
    return;
  }
  it2 = list.erase(it2);
  list.insert(it2, node1);
  list.insert(it1, *node2);
}

当然,为MyClass 量身定制这个函数几乎是荒谬的——它最好用作函数模板来处理任意类。它甚至可以按容器类型进行模板化,但在迭代器失效方面您必须更加小心。

另一种方法是在您的类 anc 调用中提供类似 swapValues() 的函数:

void MyClass:swapValues(MyClass &other)
{
  using std::swap;
  swap(nValue, other.nvalue);
  //dtto for other members, but NOT for the boost::intrusive linking structure
}

【讨论】:

  • “MyClass *node1 = *it1;”中的一些错误。错误 C2440:“正在初始化”:无法从“MyClass”转换为“MyClass *”
  • @Jimmy 抱歉,已修复。没用过Boost.Intrusive,所以对界面细节不熟悉。
  • 谢谢,但它不起作用。有一种方法可以将迭代器转换回其原始类。我需要进一步找到它...
  • 对不起,我的错!它现在正在工作......之前的一些拼写错误。
  • 我找到了第二个选项...不确定它是否足够好 "oTmpTarget1->swap_nodes(*oTmpTarget2);"
猜你喜欢
  • 2023-03-09
  • 2015-07-15
  • 1970-01-01
  • 1970-01-01
  • 2020-04-24
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
  • 2012-12-26
相关资源
最近更新 更多