C++中用于基于范围的for循环的虚拟范围初始化器
我想要一个抽象类范围初始化器,可以在基于范围的for循环中使用。这种东西真的可能吗?目前我只看到可以用非抽象类来实现。类 TestRange 充当迭代器。TestRangeB 与 TestRangeC 的内部行为不同。
#include <array>
#include <iostream>
class A {
public:
class TestRange {
public:
friend bool operator==(const TestRange& lhs, const TestRange& rhs) {
return lhs.getId() == rhs.getId();
}
friend bool operator!=(const TestRange& lhs, const TestRange& rhs) {
return !(lhs == rhs);
}
virtual int operator*() = 0;
int index = 0;
virtual int getId() const = 0;
};
class TestRangeInitializer {
public:
virtual TestRange* begin() = 0;
int end() { return -1; }
};
virtual TestRangeInitializer* getTestRangeInitializer() = 0;
};
class B : public A {
class TestRangeB : public TestRange {
public:
int getId() const override {
return index < data.size() ? data[index] : -1;
}
int operator*() override { return getId(); }
private:
std::array<int, 3> data = {1, 3, 5};
};
class TestRangeInitializerB : public TestRangeInitializer {
TestRange* begin() override {
return new TestRangeB();
}
};
TestRangeInitializer* getTestRangeInitializer() {
return new TestRangeInitializerB();
};
};
// Class C : public A;
要使用的地方:
int main() {
A* obj = new B();
for (int i : obj->getTestRangeInitializer()) {
std::cout << i << ' ';
}
}
https://godbolt.org/z/z4M9cEEsx
解决方案
你不能合理地从 begin 和 end 返回指针,因为你不能为两种指针类型提供 == 的重载,也不能从这样的指针解引用得到一个 int,而 for 被定义为使用。
如果你有子类 B 和 C,它们使用不同的容器,你可以在 A 中为 virtual boost::any_range<int> getTestRangeInitializer() = 0 提供实现。不过,可能更快的做法是把值拷贝到一个 std::vector<int>,然后返回那个。
class A {
public:
virtual std::vector<int> getTestRangeInitializer() = 0;
};
class B : public A {
std::list<int> data;
public:
std::vector<int> getTestRangeInitializer() override {
return { std::from_range, data };
}
};
class C : public A{
std::set<int> data;
public:
std::vector<int> getTestRangeInitializer() override {
return { std::from_range, data };
};
};
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。