2014-01-17 42 views
1

以下是簡單的測試程序。它試圖找到(情況1)並刪除(情況2)字符串中的第一個空格。這裏是測試結果:C++:ptr_fun()錯誤信息

1)第1行導致「沒有匹配函數調用find_if(...)」錯誤。這是因爲它試圖找到std::isspace(),而不是全球isspace()。所以第二行是好的。 2)如果使用ptr_fun()ptr_fun()一樣包裝isspace(),如第3行和第4行,第3行將導致「沒有匹配函數調用ptr_fun(...)」錯誤,第4行是好的。

3)第5行導致「沒有匹配函數調用not1(...)」錯誤。第6行會生成大量錯誤消息,包括類似「不匹配(std::unary_negate<int(int)throw()>) (char&)」的內容。

4)通過使用ptr_fun()進行包裝,第7行和第8行都可以,無論是全局還是標準的isspace()

所以:

1)爲什麼我們需要的情況下,2 ptr_fun()但不是在情況1?

2)爲什麼std::isspace()在案例2中使用ptr_fun()而在案例1中不是? isspace()如何解決?

3)ptr_fun()(和其他類似的STL函子)的真正目的是什麼?它是如何工作的?

謝謝。

#include <iostream> 
#include <algorithm> 

using namespace std; 

int main() 
{ 
    string s = " abc"; 

// case 1 (find the first space): 
// find_if(s.begin(), s.end(), isspace);    // line 1 (error) 
// find_if(s.begin(), s.end(), ::isspace);    // line 2 (ok) 

// find_if(s.begin(), s.end(), ptr_fun(isspace));  // line 3 (error) 
// find_if(s.begin(), s.end(), ptr_fun(::isspace)); // line 4 (ok) 

// case 2 (trim leading spaces): 
// s.erase(s.begin(), find_if(s.begin(), s.end(), not1((isspace)))); // line 5 (error) 
// s.erase(s.begin(), find_if(s.begin(), s.end(), not1((::isspace)))); // line 6 (error) 

// s.erase(s.begin(), find_if(s.begin(), s.end(), not1(ptr_fun<int, int>(::isspace)))); // line 7 (ok) 
// s.erase(s.begin(), find_if(s.begin(), s.end(), not1(ptr_fun<int, int>(std::isspace)))); // line 8 (ok) 

    return 0; 
} 

回答

0

首先,在使用isspace之前,您需要包含<cctype>。但是,第1行可能仍然出錯,因爲由於<locale>中提供的isspace過載導致呼叫不明確,該過載可能包含在其中包含的其他標準庫標題之一中。有沒有必要爲ptr_fun消除歧義,只使用一個static_cast

find_if(s.begin(), s.end(), static_cast<int(*)(int)>(isspace)); 

至於有關not1的問題,這需要傳遞給它的謂詞定義一個名爲argument_type類型,其包裝在ptr_fun爲你做。 ptr_fun的目的是包裝一個帶有一個或兩個參數的(非成員)函數。 C++ 11將其棄用爲std::function

如果您的編譯器支持lambda表達式,則可以清除not1ptr_fun調用。

s.erase(s.begin(), find_if(s.begin(), s.end(), [](char c) {return !isspace(c)}));