Std::for_each, operator()重载的对象不能维持状态

std::for_each, object with operator() overloaded not maintaining state

本文关键字:对象 不能 状态 重载 for each Std operator      更新时间:2023-10-16

为了回答这个问题,我编写了以下代码:

#include <string>
#include <iostream> 
#include <algorithm>
#include <vector>
class Sizes
{
public:
    void operator() ( std::vector<int> v ) { 
        sizeVec.push_back( v.size() );  
    }
    std::vector<int> sizeVec;
};
void outFunc (int i) {
    std::cout << " " << i;
}
int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<std::vector<int>> twodVec;
    std::vector<int> vec;
    vec.push_back( 6 );
    twodVec.push_back( vec );
    vec.push_back( 3 );
    twodVec.push_back( vec );
    vec.push_back( 8 );
    twodVec.push_back( vec );
    vec.push_back( 3 );
    twodVec.push_back( vec );
    Sizes sizes;
    std::for_each( twodVec.begin(), twodVec.end(), sizes );
    std::for_each( sizes.sizeVec.begin(), sizes.sizeVec.end(), outFunc );
    return 0;
}

调试显示调用了Sizes::operator(),并且sizeVec的大小按预期随着每次调用而增加。然而,当第二个std::foreach被调用时,sizeevc是空的…我已经创建了一个工作涉及到传递一个矢量到大小但是有人知道发生了什么吗

std::for_each通过值获取函子,而不是通过引用获取函子,因此原始对象不受影响。你需要做的是:

sizes = std::for_each( twodVec.begin(), twodVec.end(), sizes );

下面显示的代码片段是从我写这篇文章时引用的。

#include <string>
#include <iostream> 
#include <algorithm>
#include <vector>
class Sizes
{
public:
    void operator() ( std::vector<int> v ) { 

v是按值传递的,这可能非常低效!通过引用传递


        sizeVec.push_back( v.size() );  
    }
    std::vector<int> sizeVec;
};
void outFunc (int i) {
    std::cout << " " << i;
}
int _tmain(int argc, _TCHAR* argv[])

_tmain从来不是main的有效形式。

这段代码最多只能用微软的编译器编译。

而且,_tmain即使在Microsoft的编译器中也没有任何用途,除了针对Windows 9x的一个特殊情况(甚至不是针对Windows 9x的一般情况)。

为什么你要写更多的以使你的代码对非windows程序员来说是非标准的和不可读的?

使用标准main


{
    std::vector<std::vector<int>> twodVec;

>>可能会与大多数现代编译器一起编译,因为它们支持即将到来的c++ 0x。但是在c++ 98/c++ 03中它是无效的。所以,对于可移植的代码,还是写> >(注意空格)。


    std::vector<int> vec;
    vec.push_back( 6 );
    twodVec.push_back( vec );
    vec.push_back( 3 );
    twodVec.push_back( vec );
    vec.push_back( 8 );
    twodVec.push_back( vec );
    vec.push_back( 3 );
    twodVec.push_back( vec );
    Sizes sizes;
    std::for_each( twodVec.begin(), twodVec.end(), sizes );

sizes可以在这里自由复制,实际上是按值传递的。

但是,std::for_each返回最终结果的副本。

你可以把它赋值给sizes,即使当函子包含一个向量时,这样做是非常低效的。


    std::for_each( sizes.sizeVec.begin(), sizes.sizeVec.end(), outFunc );
    return 0;

最后的return 0;对于标准main来说是不必要的,因为它只表示标准main的默认返回值。


}

干杯,hth .

我会做一些不同的事情:

// (1) struct rather than class for functor (as it contains no state).
struct Sizes
{
    // (2) Keep a reference to the vector
    std::vector<int>&    sizeVec;
    Sizes(std::vector<int>& sizeVec): sizeVec(sizeVec) {}
    // (3) The functor can now be const as the the state is external
    void operator() ( std::vector<int> const& v ) const
    {                              //  ^^^^^^  (4) Pass parameter by const reference
                                   //              This avoids an unnecessary copy.
        sizeVec.push_back( v.size() );  
    }
};
std::for_each( twodVec.begin(), twodVec.end(), Sizes(vec) );
                                         //    ^^^^^^^^^^  Call using temporary
                                         //                No need for a Size variable.

你的第二个for_each和outFunc()可以用一些标准对象代替:

std::copy(sizes.sizeVec.begin(),
          sizes.sizeVec.end(),
          std::ostream_iterator<int>(std::cout, " ")
         );

第二个注意事项(虽然更晦涩),通过将状态排除在Sizes对象之外,可以更容易地在明年将其转换为c++ 0x lambda:

std::for_each( twodVec.begin(), twodVec.end(), Sizes(vec) );
// becomes
std::for_each( twodVec.begin(),
               twodVec.end(), 
               [&vec] ( std::vector<int> const& v ) {  vec.push_back(v.size()); }
             );