2013-05-06 23 views
6

我有一個指向類A的指針向量,我希望通過使用STL的int鍵進行排序。要做到這一點,我定義在類的operator <一個如何使用lower_bound將值插入已排序的向量

bool operator< (const A &lhs, const A &rhs){ 
    return (lhs.key < rhs.key); 
}; 

,並在我的插入功能,它看起來像

vector<A*>::iterator it = lower_bound(vec.begin(), vec.end(), element); 
vec.insert(it, element); 

我希望lower_bound回到第一個地方,新元素可以放置,但它確實不行。用鍵0,1,2,3插入一個對象將導致矢量的順序不正確(2,3,1,0)。這是爲什麼 ?

也許我還可以使用比較此對象:

compare function for upper_bound/lower_bound

但什麼是錯我的代碼?

+0

使用指針的向量是像在拍攝自己並且說'至少我錯過了我的頭'。向量的要點在於避免顯式堆內存管理,但使用指針向量意味着您仍在管理堆內存。只需使用'vector '或'vector >' – john 2013-05-06 09:18:10

+0

@John。這是爲什麼 ?如果這是不好的做法,我可能會嘗試改變它 – rank1 2013-05-06 09:22:38

+0

爲什麼是什麼?你的意思是爲什麼顯式堆內存管理不好?主要是因爲它很難並且有很多錯誤。 SO上有1000個和1000個帖子,問題在於有人沒有正確地執行他們的'new'和'delete'。這絕對被認爲是不好的做法。 – john 2013-05-06 09:24:15

回答

6

在你的例子中,你使用了一個指針向量:std::vector<A*>。因此,你需要定義你在傳遞給std::lower_bound指針的比較:

bool less_A_pointer (const A* lhs, const A* rhs) 
{ 
    return (lhs->key < rhs->key); 
} 

auto it = std::lower_bound(vec.begin(), vec.end(), element, less_A_pointer); 
//... 

當然,問題是你爲什麼要使用指針擺在首位 - 只是存儲A對象,除非你真的需要。如果你需要存儲的指針,考慮std::shared_ptr這將幫助您處理該:

std::vector<std::shared_ptr<A>> v; 
std::shared_ptr<A> element(new A(...)); 
auto it = std::lower_bound(v.begin(), v.end(), element); //Will work properly 

您還可以使用,而不必寫一個免費的功能拉姆達:如果你真的

auto it = std::lower_bound(v.begin(), v.end(), 
          [](const A* lhs, const A* rhs) 
          { return lhs->key < rhs->key; }); 
+0

不要使用指針向量將是另一種可能性。 – john 2013-05-06 09:16:06

+0

@Yuushi。錯誤:operator <'必須至少有一個類類型的形式參數。和A:GetKey':不能將'this'指針從'const A'轉換爲'A&。 int GetKey()返回私鑰。 – rank1 2013-05-06 09:20:15

+1

@ cygi1989它不是作爲操作符<'實現的,而是作爲一個自由函數... – Yuushi 2013-05-06 09:21:01

2

想要一個std::vector指針,你可能要考慮使用智能指針std::shared_ptr
指針是確定的,如果他們是觀察指針,但通常你應該使用原料owining指針(除非在某些特殊條件下)。

您可以將lambda傳遞給std::lower_bound(),以指定排序標準(在這種情況下,比較關鍵數據成員)。

而且,而是明確書面std::vector<std::shared_ptr<A>>::iteratorstd::lower_bound()的返回值,你可以只使用C++ 11的auto關鍵字,這使得代碼更易讀在這種情況下。

可編譯代碼示例如下(編譯克++ 4.8.0):

#include <algorithm> // for std::lower_bound 
#include <iostream>  // for console output 
#include <memory>  // for std::make_shared, std::shared_ptr 
#include <string>  // for std::string 
#include <vector>  // for std::vector 
using namespace std; 

// Test data structure 
struct A 
{ 
    int Key; 
    string Data; 

    A() 
     : Key(0) 
    {} 

    A(int key, const string& data) 
     : Key(key), Data(data) 
    {} 
}; 

ostream& operator<<(ostream& os, const A& a) 
{ 
    os << "(key=" << a.Key << ", data=\"" << a.Data << "\")"; 
    return os; 
} 

void Print(const vector<shared_ptr<A>> & v) 
{ 
    cout << "[ "; 
    for (const auto & p : v) 
    { 
     cout << *p << " "; 
    } 
    cout << " ]\n"; 
} 

int main() 
{ 
    // Test container 
    vector<shared_ptr<A>> v; 

    // Test data 
    const char* data[] = { 
     "hello", 
     "world", 
     "hi", 
     nullptr 
    }; 

    // Index in data array 
    int i = 0; 

    // Insertion loop 
    while (data[i] != nullptr) 
    { 
     // Create new element on the heap 
     auto elem = make_shared<A>(i, data[i]); 

     // Find ordered insertion position 
     auto it = lower_bound(v.begin(), v.end(), elem, 
      [](const shared_ptr<A>& lhs, const shared_ptr<A>& rhs) 
      { 
       return lhs->Key < lhs->Key; 
      } 
     ); 

     // Insert in vector 
     v.insert(it, elem); 

     // Move to next data 
     i++; 
    } 

    // Show the result 
    Print(v); 
} 

這裏的輸出:

[ (key=2, data="hi") (key=1, data="world") (key=0, data="hello") ]