2017-02-14 45 views
1

我是相當新的C++,並認爲它總是好的超載功能,通過重載我的意思是:爲什麼我不能重載這個比較,我傳遞到std :: UPPER_BOUND

功能用C重載++您可以在同一範圍內爲同一個函數名稱定義多個定義。函數的定義必須根據參數列表中參數的類型和/或數量相互區別。您不能重載只有返回類型不同的函數聲明。

但是,當我編寫下面的代碼時,它不能編譯,我的印象是std :: upper_bound無法解析應該使用哪個比較器,儘管看起來很簡單,因爲只有一個比較正確簽名。

編輯這些函數位於名稱空間中的實用程序文件(不是類)中。

我這樣做以下this post

我可能完全錯在這裏,你能解釋

  1. 爲什麼代碼不編譯
  2. 我怎麼能寫2執行的LT其中不同的簽名將使代碼編譯並可運行
#include <iostream> 
#include <string> 
#include <vector> 
#include <cmath> 
#include <algorithm> 

//I have a utility file where functions are defined in a namespace 
namespace util{ 
    bool lt(double y, const std::pair<double, long>& x) { 
     return x.first < y; 
    } 
    //If this function is commented the whole will compile and run 
    bool lt(const std::pair<double, long>& x, double y) { 
     return x.first < y; 
    } 
} 

int main() 
{ 
    std::vector<std::pair<double,long> > v; 
    v.push_back(std::make_pair(999., 123)); 
    v.push_back(std::make_pair(100., 3)); 
    v.push_back(std::make_pair(15., 13)); 
    v.push_back(std::make_pair(10., 12)); 
    v.push_back(std::make_pair(1., 2)); 
    //use upper_bound 
    std::vector<std::pair<double,long> >::iterator it = 
     std::upper_bound(v.begin(), v.end(), 25., util::lt); 
    std::cout << " it->first => " << it->first << std::endl; 
} 

回答

2

由於std::upper_bound是謂詞(要傳遞的功能)的類型模板,以任何的upper_bound主體的前要使用的特定的過載,必須知道被搜索(這是可以進行重載解析的地方,因爲論據是已知的)。這種情況有解決各種方式,他們沒有特別漂亮:

  • 投的確切類型:

    std::upper_bound(v.begin, v.end(), 25.0, static_cast<bool (*)(double, const std::pair<double, long>&>(lt)) 
    
  • 包裹中的呼叫拉姆達:

    [](auto x, auto y){ return lt(x, y); } 
    
  • 認沽類內部的函數,以便模板使用類的類型實例化,然後重載解析發生在模板體內:

    struct LT { 
        bool operator()(double y, const std::pair<double, long>& x) { 
         return x.first < y; 
        } 
        bool operator()(const std::pair<double, long>& x, double y) { 
         return x.first < y; 
        } 
    }; 
    // ... 
    std::upper_bound(v.begin(), v.end(), 25.0, LT()); 
    

注意,第二個2個選項幾乎同樣的事情!


事實上,我建議你停下來思考你在做什麼。在兩種完全不同的類型之間提供排序真的有意義嗎?而你的第一個功能似乎是實現gt(大於),也許它應該是return y < x.first;

我也真的考慮使用endl是一個不好的做法(我知道不是每個人都同意我的看法)。

+0

太棒了!我喜歡最後的選擇。我有一個「實用程序」文件,根據我的理解,我幾乎可以用類或結構體替換「命名空間」,使其成爲實用程序類,它將起作用!我這樣做是因爲http://stackoverflow.com/questions/8226489/organising-utility-functions-in-c – statquant

+0

'命名空間'通常對組合實用程序更有意義,但是,是的,這是你爲什麼可能會這樣做的一個原因選擇一個類(使用非'靜態'成員函數)。 – BoBTFish

3

的地方,你叫upper_bound不是調用點爲lt,所以沒有超載的分辨率在這裏發生,你的過載是不明確的。

#include <algorithm> 
#include <cmath> 
#include <iostream> 
#include <string> 
#include <vector> 

bool lt(const std::pair<double, long>& x, const std::pair<double, long>& y) 
{ 
    return x.first < y.first; 
} 

int main() 
{ 
    std::vector<std::pair<double, long>> v; 
    v.push_back(std::make_pair(999., 123)); 
    v.push_back(std::make_pair(100., 3)); 
    v.push_back(std::make_pair(15., 13)); 
    v.push_back(std::make_pair(10., 12)); 
    v.push_back(std::make_pair(1., 2)); 
    // use upper_bound 
    std::vector<std::pair<double, long>>::iterator it = 
     std::upper_bound(v.begin(), v.end(), std::make_pair(25., 0.), lt); 
    std::cout << " it->first => " << it->first << std::endl; 
} 
+1

好的,這個答案1.有沒有辦法回答2? – statquant

+0

你可以將它們包裝成一個可調用的函數 - 仿函數或labmda。 – w1ck3dg0ph3r

相關問題