2009-11-27 87 views
1

我在努力找出爲什麼我無法使用模板類進行轉換。如何在模板中使用std :: transform

這裏是模板類的簡化版本:

template<typename T> 
class base 
{ 
public : 
    base() : all_() {} 
    ~base() {} 
public: 
    bool add(T t) 
    { 
    typename vector<T>::iterator itr 
     = lower_bound(all_.begin(), all_.end(), t); 
    if (itr == all_.end() || *itr != t) 
     { 
     all_.push_back(t); 
     cout << "ok" << endl; 
     return true; 
     } 
    cout << "failed" << endl; 
    return false; 
    } 
    static bool addTo(base<T> *c, T t) 
    { 
    return c->add(t); 
    } 
private : 
    vector<T> all_; 
}; 

而這正是我試圖利用變換來捕獲所有從添加成員函數輸出的布爾:

main() 
{ 
    base<int> test; 
    vector<bool> results; 
    vector<int> toAdd; 
    toAdd.push_back(10); 
    toAdd.push_back(11); 
    toAdd.push_back(10); 
    transform(toAdd.begin(), toAdd.end(), 
      back_inserter(results), 
      bind1st((bool(*)(base<int>*,int))base<int>::addTo, &test)); 
} 

的目標是使用base :: add或base :: addTo插入toAdd容器的每個成員,並捕獲向量結果中的bool結果

+2

有什麼問題嗎?如果它是「爲什麼不編譯這個代碼」,那麼C++中的函數定義必須具有返回類型,而'main'具有返回類型'int' ;-) – 2009-11-27 17:21:30

+0

你能解釋一下你試圖在轉變? – Naveen 2009-11-27 17:23:21

+0

正確 - 無法編譯它。主要完整類型不是我使用過的任何編譯器的先決條件。 – youngthing 2009-11-27 17:23:54

回答

6

Try:

transform(toAdd.begin(), toAdd.end(), 
     back_inserter(results), 
     bind1st(mem_fun(&base<int>::add), &test)); 

問題不在於模板,而在於bind1st依靠額外的支持來工作(請參閱http://www.sgi.com/tech/stl/AdaptableBinaryFunction.html)。 AFAIK它不能在普通的舊函數指針上運行。

boost::bind可以做更多的事情,如果你想把它帶入。對於這種情況你不需要它,但:mem_fun將一個非靜態成員函數變成一個可適應的二進制函數。因此也不需要addTo,但是如果您確實需要在類似情況下使用靜態成員函數,那麼存在ptr_fun

+0

這是有效的。 感謝您的提示,特別是迂腐的提示。 – youngthing 2009-11-27 17:35:51

+0

而* reason的原理是'bind1st'不接受普通的函數指針。它需要仿函數對象。 'mem_fun'和'ptr_fun'函數將函數指針轉換爲適用於活頁夾的函子。 – 2009-11-27 17:42:37

+0

@RobKennedy:謝謝,這很有意義,還有一些我還沒有從Josutis STL書中找到。 我會給你和onebyone一個rec如果可以! – youngthing 2009-11-27 17:46:24

0

以下內容添加到您的基類:

typedef base<T>* first_argument_type; 
typedef T second_argument_type; 
typedef bool result_type; 

bool operator() (base<T> *c, T t) const { 
    return c->add(t); 
} 

和變化轉變爲:

transform(toAdd.begin(), toAdd.end(), 
      back_inserter(results), bind1st(base<int>(), &test)); 
+0

這將是好的,如果我的課(基地)只是要存儲容器 - 我不介意提交operator()只是添加一個項目。雖然我的正確代碼有更多的基地負責。 – youngthing 2009-11-27 17:40:15

+0

您不必在'base'類中添加添加,您可以創建一個小結構,比如說包含我提供的代碼的'Adder'。然後用'Adder'代替基地。但mem_fun適配器也適用;) – 2009-11-27 17:42:14