C++ 如何在c++;?
我想用这种方式实现迭代器。但编译器显示错误C++ 如何在c++;?,c++,inheritance,iterator,C++,Inheritance,Iterator,我想用这种方式实现迭代器。但编译器显示错误 class List{ public: class ListIterator{ public: }; typedef ListIterator iterator; virtual iterator begin() = 0; }; class ArrayList:public List{ public: class ArrayLi
class List{
public:
class ListIterator{
public:
};
typedef ListIterator iterator;
virtual iterator begin() = 0;
};
class ArrayList:public List{
public:
class ArrayListIterator{
public:
};
typedef ArrayListIterator iterator;
iterator begin(){
}
};
class LinkedList:public List{
public:
class LinkedListIterator{
public:
};
typedef LinkedListIterator iterator;
iterator begin(){
}
};
LinkedList也是如此
当我在堆栈溢出上搜索相同的问题时,我得到了这个解决方案
我有两个解决方案
[Error] invalid covariant return type for 'virtual ArrayList::iterator ArrayList::begin()'
[Error] overriding 'virtual List::iterator List::begin()'
但我想知道,有没有任何可能的方法使迭代器成为ArrayList、LinkedList和List的内部类???您需要ArrayListIterator从ListIterator派生 派生类中begin返回的类型不是从基列表类中begin返回的类型派生的
这就是为什么错误说它们不是协变的。您需要抛弃基于继承的多态性。标准库中的C++迭代和<>代码>(:)/Cord>Road假定基于值的迭代器,基于继承的多态性与基于值的迭代器不起作用。 您应该使用基于类型擦除的多态性,而不是基于继承的多态性。这需要一点样板,因为抽象处理一个迭代范围的需求在C++中并不常见,而且经常是严重的性能命中。 但我会告诉你怎么做 基于类型擦除的多态性类似于
std::function
消除类型多态性的一种具体方法:
您可以确定要支持的接口。称之为“类型擦除目标”。您的类型擦除目标不是一个具有virtual
和=0
的类,而是一组您想要支持的函数、方法和操作,以及它们的签名,以及对每个函数、方法和操作的描述
然后编写一个值类来实现该接口(同样,没有继承),该接口包含一个pImpl
(请参见pImpl
模式),它将其操作分派给该接口(pImpl不需要匹配相同的接口,它只需要可以实现操作的原语。在这里最小化是值得的)
pImpl
类型确实有virtual
方法和=0
抽象方法
然后编写一个构造函数或工厂函数,该函数接受一个支持所需接口的对象,并生成pImpl
的具体实例,然后将值类包装在其周围
假设类型擦除目标是“打印到流”
<我的类型擦除目标是
1 . implement iterator without using runtime polymorphism
2 . implement seperator iterator class.
struct printable_view {
// dispatch to pimpl:
friend std::ostream& operator<<( std::ostream& o, printable_view const& p ) {
p->print(o);
return o;
}
// pimpl:
private:
struct printable_view_impl {
virtual ~printable_view_impl() {}
virtual void print(std::ostream& o) = 0;
};
std::unique_ptr<printable_view_impl> pImpl;
private:
template<class T>
struct printer:printable_view_impl {
printer( T const* p ):ptr(p) {}
T const* ptr; // just a view, no ownership
virtual void print( std::ostream& o ) final override {
o << *ptr;
}
};
public:
// create a pimpl:
printable_view(printable_view&&)=default;
printable_view(printable_view const&)=delete;
printable_view()=delete;
template<class T>
printable_view( T const& t ):
pImpl( std::make_unique<printer<T>>( std::addressof(t) ) )
{}
};
template<class T>
struct any_iterator_sorta {
T operator*()const { return pImpl->get(); }
void operator++() { pImpl->next(); }
any_iterator_sorta(any_iterator_sorta const& o):
any_iterator_sorta( o.pImpl?any_iterator_sorta(o.pImpl->clone()):any_iterator_sorta() )
{}
friend bool operator==(any_iterator_sorta const& lhs, any_iterator_sorta const& rhs ) {
if (!lhs.pImpl || ! rhs.pImpl)
return lhs.pImpl == rhs.pImpl;
return lhs.pImpl->equals( *rhs.pImpl );
}
friend bool operator!=(any_iterator_sorta const& lhs, any_iterator_sorta const& rhs ) {
return !(lhs==rhs);
}
any_iterator_sorta(any_iterator_sorta&& o) = default;
any_iterator_sorta() = default;
any_iterator_sorta& operator=(any_iterator_sorta const& o) {
any_iterator_sorta tmp=o;
std::swap(tmp.pImpl, o.pImpl);
return *this;
}
any_iterator_sorta& operator=(any_iterator_sorta&& o) = default;
private:
struct pimpl {
virtual ~pimpl() {}
virtual void next() = 0;
virtual T get() const = 0;
virtual std::unique_ptr< pimpl > clone() const = 0;
virtual bool equals( pimpl const& rhs ) const = 0;
};
std::unique_ptr< pimpl > pImpl;
template<class It>
struct pimpl_impl:pimpl {
It it;
virtual void next() final override { ++it; }
virtual T get() const final override { return *it; }
virtual std::unique_ptr< pimpl > clone() const final override {
return std::make_unique<pimpl_impl>( it );
}
virtual bool equals( pimpl const& rhs ) const final override {
if (auto* r = dynamic_cast<pimpl_impl const*>(&rhs))
return it == r->it;
return false;
}
pimpl_impl( It in ):it(std::move(in)) {}
};
any_iterator_sorta( std::unique_ptr< pimpl > pin ):pImpl(std::move(pin)) {}
public:
template<class It,
std::enable_if_t< !std::is_same<It, any_iterator_sorta>{}, int>* =nullptr
>
any_iterator_sorta( It it ):
pImpl( std::make_unique<pimpl_impl<It>>( std::move(it) ) )
{}
};
void test( any_iterator_sorta<int> begin, any_iterator_sorta<int> end )
{
for (auto it = begin; it != end; ++it) {
std::cout << *it << '\n';
}
}
std::vector<int> v{1,2,3};
std::list<int> l{10,11};
test( begin(v), end(v) );
test( begin(l), end(l) );
virtual any_iterator_sorta<int> begin() = 0;
virtual any_iterator_sorta<int> end() = 0;
any_iterator_sorta<int> begin() final override {
return ArrayListIterator{};
}
any_iterator_sorta<int> end() final override {
return ArrayListIterator{};
}
class ArrayListIterator{
public:
int operator*() const { return 0; }
bool operator==( ArrayListIterator const& o ){return true;}
void operator++() { /* do nothing for now */ }
};