2011-07-29 46 views
8

這是一個非常簡單的repro,它說明class Predicate如何在main()以外工作,但是當確切代碼內嵌爲class InlinePredicate時,編譯器不能匹配std::sort。奇怪的是,你可以通過任何東西作爲std::sort(比如說整數7)的第三個參數,當它不支持sort期望的operator()時,你會得到一個編譯錯誤。但是,當我通過pred2下面不匹配都:爲什麼這個std :: sort謂詞失敗,當類在main()內?

#include <string> 
#include <vector> 
#include <algorithm> 

using namespace std; 

class Predicate { 
public: 
    bool operator() (const pair<string,int>& a, const pair<string,int>& b) 
    { 
     return a.second < b.second; 
    } 
}; 

int 
main() 
{ 
    vector<pair<string, int> > a; 

    Predicate pred; 
    sort(a.begin(), a.end(), pred); 

    class InlinePredicate { 
    public: 
     bool operator() (const pair<string,int>& a, const pair<string,int>& b) 
     { 
      return a.second < b.second; 
     } 
    } pred2; 
    sort(a.begin(), a.end(), pred2); 

    return 0; 
} 

repro.cc: In function ‘int main()’:

repro.cc:30: error: no matching function for call to ‘sort(__gnu_cxx::__normal_iterator, std::allocator >, int>*, std::vector, std::allocator >, int>, std::allocator, std::allocator >, int> > > >, __gnu_cxx::__normal_iterator, std::allocator >, int>*, std::vector, std::allocator >, int>, std::allocator, std::allocator >, int> > > >, main()::InlinePredicate&)’

+1

補充說明:您的運營商可能應該是const'布爾運算符()(常量對&A,常量對&B)** **常量' –

回答

9

在C++ 03,本地類沒有聯繫,因此不能作爲模板參數(§14.3.1/ 2 )。

在C++ 0x中,此限制已被刪除,您的代碼將按原樣編譯。

+1

您應該仍然可以使謂詞的運算符爲'const',因爲'sort'可能需要這樣做。 –

+0

它用'g ++ -std = C++ 0x'編譯爲GCC 4.5(不是4.3,我沒有4.4方便) –

5

在C++ 0x之前的C++版本中,在函數內聲明的類不能出現在模板參數中。您調用sort隱式地將其實例化爲模板參數設置爲InlinePredicate,這是非法的。您可以考慮使用C++ 0x(使用GCC,通過--std=c++0x;在C++ 0x中,此代碼將按原樣運行,或者您可以使用匿名函數)或boost::lambda。隨着boost::lambda,它應該是這樣的:

using namespace boost::lambda; 

sort(a.begin(), a.end(), _1 < _2); 
+1

請注意,從Boost 1.47開始,Boost.Lambda被官方棄用,贊成[Boost .Phoenix v3](http://www.boost.org/doc/libs/release/libs/phoenix/)。因此,使用Phoenix而不是Lambda可以更好地使用新代碼(並且您爲'sort'調用顯示的語法將保持相同)。 – ildjarn

+0

@ildjarn,哦很棒,_yet another_ C++ 03匿名函數hack學習... :) – bdonlan

+0

但是更強大的一個,絕對值得。 : - ]即使在C++ 0x中,我也傾向於在大約一半時間內使用C++ 0x lambdas的Phoenix函數,因爲它們是多態的。 – ildjarn