这是一个基于 C++20 的解决方案(部分实现)...只是想我会把它放在那里。
它使用带有堆栈存储而不是多态和动态分配的变体,因此它可能具有更好的性能。
它应该适用于具有公共value_type 并且其reference 类型为value_type& 的任何给定迭代器类型集。它也应该相当容易适应其他类型的迭代器并包含operator->。
不声称这比原始答案中的实现更好。只是一个有趣的选择......
PS。以下名称中的normal 仅表示基于基本指针的迭代器。
template <typename _Iterator, typename _Value, typename _Reference, typename _Difference>
concept forward_iterator_for
= std::forward_iterator<_Iterator>
&& std::same_as<std::iter_value_t<_Iterator>, _Value>
&& std::same_as<std::iter_reference_t<_Iterator>, _Reference>
&& std::same_as<std::iter_difference_t<_Iterator>, _Difference>;
template <typename _Iterator, typename _Value>
concept normal_forward_iterator_for //
= std::same_as<std::remove_cvref_t<_Value>, std::remove_const_t<_Value>>
&& forward_iterator_for<_Iterator, std::remove_const_t<_Value>, _Value&, std::ptrdiff_t>;
template <typename _Value, normal_forward_iterator_for<_Value> ... _Iterator>
class normal_forward_iterator_variant {
public:
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = std::remove_cv_t<_Value>;
using reference = _Value&;
using iterator_type = std::variant<_Iterator...>;
private:
iterator_type _m_iter;
public:
normal_forward_iterator_variant() = default;
template <normal_forward_iterator_for<_Value> _Iter, typename... _Args>
normal_forward_iterator_variant(std::in_place_type_t<_Iter>, _Args&&... args)
noexcept (std::is_nothrow_constructible_v<_Iter, _Args&&...>)
: _m_iter(std::in_place_type<_Iter>, std::forward<_Args>(args)...) {}
normal_forward_iterator_variant(iterator_type const& iter)
noexcept (std::is_nothrow_copy_constructible_v<iterator_type>)
: _m_iter(iter) {}
normal_forward_iterator_variant(normal_forward_iterator_variant const&) = default;
normal_forward_iterator_variant(normal_forward_iterator_variant&&) = default;
constexpr normal_forward_iterator_variant&
operator=(normal_forward_iterator_variant const& iter)
noexcept (std::is_nothrow_copy_assignable_v<iterator_type>) //
requires std::is_copy_assignable_v<iterator_type> {
_m_iter = iter._m_iter;
return *this;
}
constexpr normal_forward_iterator_variant&
operator=(normal_forward_iterator_variant&& iter)
noexcept (std::is_nothrow_move_assignable_v<iterator_type>) //
requires std::is_move_assignable_v<iterator_type> {
_m_iter = std::move(iter._m_iter);
return *this;
}
template <typename _Tp>
constexpr normal_forward_iterator_variant&
operator=(_Tp const& x)
noexcept (std::is_nothrow_assignable_v<iterator_type, _Tp&>) //
requires std::is_assignable_v<iterator_type, _Tp&> {
_m_iter = x;
return *this;
}
template <typename _Tp>
constexpr normal_forward_iterator_variant&
operator=(_Tp&& x)
noexcept (std::is_nothrow_assignable_v<iterator_type, _Tp&&>) //
requires std::is_assignable_v<iterator_type, _Tp&&> {
_m_iter = std::move(x);
return *this;
}
[[nodiscard]] constexpr reference
operator*() const noexcept {
return std::visit([](auto&& iter) -> reference {
return *iter;
}, _m_iter);
}
constexpr normal_forward_iterator_variant&
operator++() noexcept {
std::visit([](auto&& iter) {
++iter;
}, _m_iter);
return *this;
}
constexpr normal_forward_iterator_variant
operator++(int) noexcept {
normal_forward_iterator_variant rv(*this);
++*this;
return rv;
}
[[nodiscard]] friend constexpr bool
operator==(normal_forward_iterator_variant const& a, normal_forward_iterator_variant const& b) noexcept {
return (a._m_iter == b._m_iter);
}
};
使用示例:
#include <iostream>
#include <iomanip>
#include <vector>
#include <list>
#include <iterator.h>
int
main() {
using vector = std::vector<int>;
using list = std::list<int>;
using iterator = normal_forward_iterator_variant<const int, vector::const_iterator, list::const_iterator>;
iterator iter;
vector v{ 0, 1, 2 };
iter = v.cbegin();
std::cout << *iter++ << std::endl;
std::cout << *iter << std::endl;
std::cout << *++iter << std::endl;
list l{ 3, 4, 5 };
iter = l.cbegin();
std::cout << *iter++ << std::endl;
std::cout << *iter << std::endl;
std::cout << *++iter << std::endl;
}
如预期的那样,输出为 1、2、...、6。