gpt4 book ai didi

c++ - 如何多态地使用 copy_if()?

转载 作者:搜寻专家 更新时间:2023-10-31 01:08:18 24 4
gpt4 key购买 nike

此代码尝试在多态指针 vector 上使用 copy_if():

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

class AbstractBase
{
public:
virtual bool IsDerived1() const { return false; }
virtual void Print() const = 0;
};

class Derived1 : public AbstractBase
{
public:
virtual bool IsDerived1() const { return true; }
virtual void Print() const { cout << "Derived1" << endl; }
};

class Derived2 : public AbstractBase
{
public:
virtual void Print() const { cout << "Derived2" << endl; }
};

// This function returns the elements of v that are of type Derived1.
vector<Derived1*> SelectDerived1(const vector<AbstractBase*>& v)
{
vector<Derived1*> derived1s;

#define USE_COPY_IF 0

#if USE_COPY_IF
// attempt to use copy_if - does not compile:
// /usr/include/c++/4.7/bits/stl_algo.h:990:6:
// error: invalid conversion from 'AbstractBase*' to 'Derived1*'
// [-fpermissive]
copy_if(v.begin(), v.end(), derived1s.begin(),
[](AbstractBase* elem){ return elem->IsDerived1(); });
#else
for (auto it = v.begin(); it != v.end(); ++it)
if ((*it)->IsDerived1())
derived1s.push_back(static_cast<Derived1*>(*it));
#endif

return derived1s;
}

int main()
{
vector<AbstractBase*> v;
Derived1* d1 = new Derived1;
Derived2* d2 = new Derived2;
v.push_back(d1);
v.push_back(d2);

vector<Derived1*> derived1s = SelectDerived1(v);
for (auto it = derived1s.begin(); it != derived1s.end(); ++it)
(*it)->Print();

delete d1;
delete d2;

return 0;
}

代码编译并在 USE_COPY_IF 设置为 0 时正常工作:

$ g++ -std=c++11 test_copy_if.cc
$ ./a.out
Derived1

但我无法让它与 copy_if() 一起工作 - 请参阅评论中的错误消息。

有没有办法?

最佳答案

您可能想要定义一个函数 transform_if(标准中没有):

template <class InIt, class OutIt, class Pred, class Trafo>
OutIt transform_if (
InIt begin_in, InIt end_in,
OutIt begin_out,
Pred predicate,
Trafo trafo
) {
OutIt itout = begin_out;
for (InIt itin = begin_in; itin != end_in; ++itin) {
if (predicate (*itin)) {
(*itout) = trafo (*itin);
++itout;
}
}
}

然后你可以这样写:

transform_if(v.begin(), v.end(), derived1s.begin(),
[](AbstractBase* elem){ return elem->IsDerived1(); },
[](AbstractBase* elem){ return static_cast<Derived1*> (elem); }
);

或者定义一个transform_and_keep_if做转换后的检查:

template <class InIt, class OutIt, class Trafo, class Pred>
OutIt transform_and_keep_if (
InIt begin_in, InIt end_in,
OutIt begin_out,
Trafo trafo,
Pred predicate
) {
OutIt itout = begin_out;
for (InIt itin = begin_in; itin != end_in; ++itin) {
auto transformed = trafo (*itin);
if (predicate (transformed)) {
(*itout) = transformed; // or std::move (transformed)
++itout;
}
}
}

然后写:

transform_and_keep_if(v.begin(), v.end(), derived1s.begin(),
[](AbstractBase* elem){ return dynamic_cast<Derived1*> (elem); },
[](Derived1* elem){ return elem != NULL; },
);

关于c++ - 如何多态地使用 copy_if()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18161884/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com