3

我有一个名为“UltrasoundTemplate”的课程。这些 UltrasoundTemplate 对象包含一个 int 参数,该参数显示它们的定义时间(类似于时间戳)。我有一个名为“UltrasoundTarget”的类,其中包含 UltrasoundTemplate 的向量。我使用 push_back(ultrasoundTemplate) 将 UltrasoundTemplates 添加到向量中。

现在我想按时间戳的顺序对向量进行排序,而不是按我将它们添加到向量中的顺序。

我在 google 中找到了很多答案,它们都向我展示了相同的解决方案,但显然我仍然做错了什么。以下是我认为找到解决方案所必需的代码片段:

超声波模板.h

class UltrasoundTemplate
{
public:
 UltrasoundTemplate(/*...*/);
 int getVolumePos() { return volume_; }
private:
 int volume_;
};

超声目标.h

//the sort algorithm
struct MyTemplateSort {
bool operator() ( UltrasoundTemplate t1, UltrasoundTemplate t2){
    int it1 = t1.getVolumePos();
    int it2 = t2.getVolumePos();

    if (it1 < it2)
        return true;
    return false;
}
};

class UltrasoundTarget
{
public:
 UltrasoundTarget(/*...*/);
 vector<UltrasoundTemplate> getTemplates() { return USTemplateVector_; }
private:
 vector<UltrasoundTemplate> USTemplateVector_;
};

FMainWindow.cpp

void FMainWindow::match_slot()
{
 int i;
 //here I get the name of the target I'm looking for
 QTreeWidgetItem *item = targetInfoWidget_->treeWidget->currentItem();
 int index = targetInfoWidget_->treeWidget->indexOfTopLevelItem(item);
 QString itemToAppendName = item->text(0);
 for(i = 0; i < USTargetVector.size(); i++){
  if(USTargetVector.at(i).getName() == itemToAppendName) {
   //here I try to sort
   MyTemplateSort tmpltSrt;
   std::sort(USTargetVector.at(i).getTemplates().begin(),
              USTargetVector.at(i).getTemplates().end(), tmpltSrt);     
   break;
  }
 }

例如:我在 Volume(0) 中定义 Template1,在 Volume(70) 中定义 Template2,在 Volume(40) 中定义 Template3。现在的顺序是 (Template1, Template2, Template3) 但我希望它是 (Template1, Template3, Template2)。但是这段代码没有这样做。

如果缺少信息,请告诉我,我会提供更多代码。

非常感谢。

4

2 回答 2

5

您的getTemplates()方法按值返回,在这里弄得一团糟:

std::sort(USTargetVector.at(i).getTemplates().begin(),
          USTargetVector.at(i).getTemplates().end(), tmpltSrt);     

您正在对不兼容的迭代器范围进行排序。您可以通过返回参考来解决该特定问题:

vector<UltrasoundTemplate>& getTemplates() { return USTemplateVector_; }

const为这样的方法添加重载是常见的做法:

const vector<UltrasoundTemplate>& getTemplates() const { return USTemplateVector_; }

您还可以修改比较函子以避免不必要的副本(以及一般可读性和 const 正确性):

struct MyTemplateSort {
  bool operator() const ( const UltrasoundTemplate& t1, const UltrasoundTemplate& t2)
  {
    return t1.getVolumePos() < t2.getVolumePos();
  }
};

这将要求您创建getVolumePos()一个const方法,无论如何它都应该是:

class UltrasoundTemplate
{
public:
 ...
 int getVolumePos() const { return volume_; }
 ...
};

请注意,提供对类的私有数据的引用通常不是好的做法。如果可能,您应该找到一种方法将其从UltraSoundTarget界面中删除。例如,您可以公开一对迭代器,和/或给类一个排序方法。

于 2013-09-30T13:28:39.403 回答
0

juanchopanza 的答案是正确的,问题是您从 UltrasoundTarget 返回向量的方式。只是为了触及另一个话题,也许稍微改变一下你的实现设计会很好。由于 UltrasoundTarget 是 Ultrasound 的容器,因此将排序实现为此类的方法是有意义的,这样您就可以直接访问 USTemplateVector_ 并节省不必要的副本。就像是:

class UltrasoundTarget
{
public:
 UltrasoundTarget(/*...*/);
 vector<UltrasoundTemplate> getTemplates() { return USTemplateVector_; }

 void sort();

private:
 vector<UltrasoundTemplate> USTemplateVector_;
};

void UltrasoundTarget::sort()
{
 std::sort(USTemplateVector_.begin(), USTemplateVector_.end(), tmpltSrt);  
}

void FMainWindow::match_slot()
{
 int i;
 //here I get the name of the target I'm looking for
 QTreeWidgetItem *item = targetInfoWidget_->treeWidget->currentItem();
 int index = targetInfoWidget_->treeWidget->indexOfTopLevelItem(item);
 QString itemToAppendName = item->text(0);
 for(i = 0; i < USTargetVector.size(); i++){
 if(USTargetVector.at(i).getName() == itemToAppendName) 
 {
   //here I try to sort
   MyTemplateSort tmpltSrt;
   USTargetVector.at(i).sort(); 
   break;
 }
}
于 2013-09-30T13:41:01.663 回答