2014-07-23 74 views
1

對於較新的C++功能,你經常給一個函數作爲參數,例如:將for_each調用的函數放在類中的位置?

// File A.cpp  

void do_something(Foo* foo) { ... } 

void A::process_foo(){ 
    for_each(foo_list.begin(), foo_list.end(), do_something); 
} 

但我應該在哪裏居然把功能do_something(...)時,我連班工作?我不能讓它成爲私人成員,因爲在將參數傳遞給for_each時,我會鬆動this

所以我傾向於在我的實現文件A.cpp中定義一個普通函數do_something(...),就像上面代碼中給出的一樣。由於這僅通過實施A可見,所以我不會冒名稱空間污染的風險。由於其他類中的類似函數也只能在其實現中可見,因此我也不會冒險與另一類的類似函數發生名稱衝突。

這是正確的方法嗎?

另一個想法是使用Lambda。我對Lambdas不是很熟悉,所以我不知道我是應該儘可能多還是僅僅在絕對必要時使用它們...

+1

蘭姆達斯很容易,當你知道如何。 ''for_each(foo_list.begin(),foo_list.end(),[](Foo * foo){foo-> something();});' –

+1

也許你正在尋找'Foo * '?如果你願意的話,這也可能是「私人」的。使用'std :: bind'的 – nwp

+1

將允許'do_something'爲私有的... – Theolodis

回答

1

std::for_each的第三個參數需要是函數或函數對象參數,例如它可以用由前兩個參數for_each定義的範圍的元素來調用。那麼你有以下選項(假設foo_listFoo*):

使用定時功能

void do_someting(Foo*){...} 
for_each(..., do_something); 

你可以把功能無論它是合適的。如果這是本地使用,匿名命名空間是最好的選擇。但它可能是例如在單獨的編譯單元中定義。

使用靜態方法

static void do_something(Foo*){...} 
for_each(..., &Foo::do_something); 

注意,它並不需要一定是的Foo靜態方法。

使用拉姆達

for_each(...,[](Foo* f){...}); 

使用Foo類的方法(甚至私人)和std::bind

void method(){...} 
for_each(..., std::bind(&Foo::method, _1)); 

還有其他的選擇,但這些都是最常見的。

+0

匿名命名空間=函數的命名空間放在我的.cpp文件中,沒有更多的命名空間規範? – Michael

+0

匿名命名空間=='namespace {}'通常在.cpp –

1

C++ 11的解決方案

如果你可以使用C++ 11,寧可範圍爲基礎的,而不是std::for_each和只寫就地代碼。像這樣:

for (const auto& value : foo_list) 
{ 
    // do something with the value 
} 

它不那麼冗長和更方便。它會逐個遍歷所有元素,就像std::for_each算法一樣。你可以明確地指定你不想通過將const auto&或簡單地auto(不帶參考)來修改元素。

部分-C++ 11

如果你的編譯器不支持基於範圍的FORS的,但支持的lambda表達式(如Visual Studio 2010),簡單地說功能入λ:

for_each(foo_list.begin(), foo_list.end(), 
    [] (const FooList::value_type& value) { /* do something with the value */; }); 

C++ 98

如果可以不使用以上C++ 11的特性,大多數的STL算法看起來可憐。無論您將do_something函數放在哪個函數中,它都將與調用代碼解耦,這很難讀取。不想基於迭代器在這種情況下簡單:

for (FooList::iterator pValue = foo_list.begin(); pValue != foo_list.end(); ++pValue) 
{ 
    // do something with the pValue 
} 

PS我喜歡甚至「部分 - C++ 11」的情況下,當你無法使用基於範圍的維權後一種形式,但可以替代FooList::iterator用簡單的auto。當你需要寫更復雜的東西時,這非常有用,例如std::list<std::string>::const_iterator。我認爲以下比std::for_each更好用lambda:

for (auto pValue = foo_list.begin(); pValue != foo_list.end(); ++pValue) 
{ 
    // do something with the pValue 
} 
+0

這是一個詳盡的答案,但是對於另一個問題;-)我主要不是問如何遍歷aa向量,而是在何處實際上放了一個像for_each(...)那樣的函數。但是,無論如何,它會給出一些有關如何遍歷矢量的好主意。 – Michael

+0

@Michael Hm,好的,無論:) – Mikhail

相關問題