2014-07-23 72 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

相关问题