从另一个向量类型中包含的组件构建向量

发布于 2024-07-29 08:43:16 字数 683 浏览 4 评论 0原文

我有一个看起来像这样的代码:

struct First
{
    int f1;
    int f2;
};

struct Second
{
    First s1;
    int s2;
};

std::vector < Second > secondVec;

Second sec;
sec.s1 = First(); 

secondVec.push_back(sec);
secondVec.push_back(sec);

std::vector < First > firstVec;
firstVec.reserve(secondVec.size());

for (std::vector < Second >::iterator secIter = secondVec.begin(); 
         secIter != = secondVec.end();
         ++secIter)
{
    firstVec.push_back(secIter->s1);
}

我想用一个简单的 stl 函数替换这个丑陋的 for 循环,该函数也许可以执行等效的过程。 我想也许 std::transform 可以在这里帮助我,但我不确定如何编写它。

我也很感兴趣 boost 是否能在这里提供任何东西。

I have a code that looks something like this:

struct First
{
    int f1;
    int f2;
};

struct Second
{
    First s1;
    int s2;
};

std::vector < Second > secondVec;

Second sec;
sec.s1 = First(); 

secondVec.push_back(sec);
secondVec.push_back(sec);

std::vector < First > firstVec;
firstVec.reserve(secondVec.size());

for (std::vector < Second >::iterator secIter = secondVec.begin(); 
         secIter != = secondVec.end();
         ++secIter)
{
    firstVec.push_back(secIter->s1);
}

I'd like to replace this ugly for loop with a simple stl function that could perhaps perform the equivalent process. I was thinking that maybe std::transform could help me here, but I'm unsure as to how this could be written.

I'd also be interested if boost has anything to offer here.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

向地狱狂奔 2024-08-05 08:43:16

如果您有 TR1 或 Boost 可用,您可以尝试以下操作:

std::transform(secondVec.begin(),
               secondVec.end(),
               std::back_inserter(firstVec),
               std::tr1::bind(&Second::s1, _1));

If you have TR1 or Boost available, you could try this:

std::transform(secondVec.begin(),
               secondVec.end(),
               std::back_inserter(firstVec),
               std::tr1::bind(&Second::s1, _1));
你的呼吸 2024-08-05 08:43:16

定义将 Second 转换为 First 的函子:

struct StoF { First operator()( const Second& s ) const { return s.s1; } };

然后按以下方式使用它:

transform( secondVec.begin(), secondVec.end(), back_inserter(firstVec), StoF() );

如果源向量包含很多元素,则应考虑调整目标向量的大小以使其工作更快,如 @Goz 答案中所示:

firstVec.resize( secondVec.size() );
transform( secondVec.begin(), secondVec.end(), firstVec.begin(), StoF() );

Define functor that will transform Second to First:

struct StoF { First operator()( const Second& s ) const { return s.s1; } };

Then use it in the following way:

transform( secondVec.begin(), secondVec.end(), back_inserter(firstVec), StoF() );

If your source vector contains a lot of elements you should consider resizing destination vector to make it work faster, as in @Goz answer:

firstVec.resize( secondVec.size() );
transform( secondVec.begin(), secondVec.end(), firstVec.begin(), StoF() );
瞳孔里扚悲伤 2024-08-05 08:43:16

这并不是特别困难......我尝试过这个,没有任何问题。

struct First
{
    int f1;
    int f2;
};

struct Second
{
    First s1;
    int s2;
};

First Replace( Second& sec )
{
    return sec.s1;
}

然后使用以下代码复制它

std::vector < Second > secondVec;

Second sec;
sec.s1.f1 = 0; 
sec.s1.f2 = 1; 
secondVec.push_back(sec);

sec.s1.f1 = 2; 
sec.s1.f2 = 3; 
secondVec.push_back(sec);

std::vector < First > firstVec;
firstVec.resize( secondVec.size() );
std::transform( secondVec.begin(), secondVec.end(), firstVec.begin(), Replace );

Its not particularly difficult ... I tried this and it worked no problems.

struct First
{
    int f1;
    int f2;
};

struct Second
{
    First s1;
    int s2;
};

First Replace( Second& sec )
{
    return sec.s1;
}

and then used the following code to copy it

std::vector < Second > secondVec;

Second sec;
sec.s1.f1 = 0; 
sec.s1.f2 = 1; 
secondVec.push_back(sec);

sec.s1.f1 = 2; 
sec.s1.f2 = 3; 
secondVec.push_back(sec);

std::vector < First > firstVec;
firstVec.resize( secondVec.size() );
std::transform( secondVec.begin(), secondVec.end(), firstVec.begin(), Replace );
雨夜星沙 2024-08-05 08:43:16

你的直觉是对的。 尽管由于您使用的是空向量,但您应该为输出迭代器使用后插入器

它应该看起来像这样:

std::transform(secondVec.being(), secondVec.end(), back_inserter(firstVec), yourFunctor)

你的函子看起来像这样:

void youFunctor(First param)
{
  return param.s1;
}

编辑:Boost 可以帮助你使用 lambda 函数,这样你就不必为此任务创建一个单独的函子。 您还应该注意,lambda 函数是 TR1 的一部分,并将集成到 C++ 标准库中。

编辑:这是 Meredith 与 mem_fun (或成员函数适配器)谈论的内容。

 struct Second
{
    First s1;
    int s2;
    First getS1() const {return s1;};
};

然后转换将如下所示:

std::transform(secondVec.being(), 
               secondVec.end(), 
               std::back_inserter(firstVec), 
               std::mem_fun(&Second::getS1))

You were right with your intuition. Although since you are using an empty vector, you should use a back inserter for your output iterator.

It should look like something of the like :

std::transform(secondVec.being(), secondVec.end(), back_inserter(firstVec), yourFunctor)

And yourFunctor looking like this :

void youFunctor(First param)
{
  return param.s1;
}

Edit : Boost could help you with lambda function so you wouldn't have to create a separate functor for this task. You should also note that lambda function function are part of the TR1 and will be integrated to the C++ standard library.

Edit : Here is what Meredith was talking about with mem_fun (or member function adaptor).

 struct Second
{
    First s1;
    int s2;
    First getS1() const {return s1;};
};

And then the transform would look like this :

std::transform(secondVec.being(), 
               secondVec.end(), 
               std::back_inserter(firstVec), 
               std::mem_fun(&Second::getS1))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文