2014-09-29 69 views
2

假設我有這個類(STD從繼承:: vector的,這只是一個例子)如何在for_each方法中使用自己的類的函數?

#include <vector> 

using namespace std; 

template <class T> 
class C : public vector<T> { 

    // I don't want to use static keyword 
    void transformation(T i) { 
     i *= 100; 
    } 

    public: 
    void method() { 
     for_each(this->begin(), this->end(), transformation); 
    } 
}; 

int main() { 
    C<double> c; 
    for (int i=-3; i<4; ++i) { 
     c.push_back(i); 
    } 

    c.method(); 
} 

我怎麼叫的for_each使用內部類本身類的方法?我知道我可以使用靜態關鍵字,但有什麼其他方式如何使用函數對象而不使用靜態?

我收到此錯誤信息在編譯:

for_each.cc:21:55: error: cannot convert ‘C::transformation’ from type ‘void (C::)(double)’ to type ‘void (C::*)(double)’ for_each(this->begin(), this->end(), transformation);

我想我需要添加.*->*的地方,但我不能找出爲什麼。

+0

嗯,我想我在這裏找到了一個解決方案:http://stackoverflow.com/questions/18006685/call-a-member-function-using-for-each – 2014-09-29 11:41:17

+0

lambda解決方案呢?(this-> begin(),this-> end(),[this](T&ob){transformation(ob);}); – 2014-09-29 11:42:22

+1

您可能想要'void transformation(T & i);',而不是'void transformation(T i);'。 – aschepler 2014-09-29 11:44:13

回答

14

C++ 11 綁定溶液:

std::for_each(this->begin(), this->end(), 
     std::bind(&C::transformation, this, std::placeholders::_1)); 

C++ 11 拉姆達溶液:

std::for_each(this->begin(), this->end(), 
     [this] (T& i) { transformation(i); }); 

C++ 14 通用拉姆達溶液:

std::for_each(this->begin(), this->end(), 
     [this] (auto&& i) { transformation(std::forward<decltype(i)>(i)); }); 

C++ 98 bind1st + mem_fun溶液:

std::for_each(this->begin(), this->end(), 
     std::bind1st(std::mem_fun(&C::transformation), this)); 

注:this->begin()this->end()呼叫有資格與this->只因爲在OP的代碼它們是模板化基類的成員函數。因此,這些名稱在全局名稱空間中初始搜索。任何其他發生的this是強制性的。

3

對於初學者,不要繼承自標準容器,它們不是被設計爲被繼承的(沒有虛擬析構器等)。

其次,關於您的問題,這是因爲指向成員函數的指針與指向函數的指針不同。原因是成員函數有一個隱藏的第一個參數,它變成函數中的this指針。解決這個問題的最簡單的方法是使功能static

另一種解決方案是使用與C++ 11傳來std::bind功能:

for_each(this->begin(), this->end(), 
    std::bind(&C::transformation, this, std::placeholders::_1)); 

如果有C++ 11(即使你標記你的問題是這樣的),那麼你可能可以通過std::mem_funstd::bind1st得到一些東西。

+0

只要不使用多態,標準容器的繼承就沒有問題。多態不是使用繼承的唯一原因,並且可以有從標準容器繼承的有用的應用程序。 – 2015-06-27 20:05:14

0

需要將this指針結合:

public: 
void method() 
{ 
    for_each(this->begin(), this->end(), bind(&C::transformation, this, placeholders::_1)); 
} 
相關問題