解构问题
迭代器具有值语义。因此它们的生命周期总是与周围对象的生命周期或其存储持续时间绑定(堆栈用于自动,堆用于动态,有时甚至其他对象例如静态)。
我想你想了解validity而是迭代器。
Well, 文档显示 http://www.boost.org/doc/libs/1_65_1/doc/html/boost_asio/reference/ip__basic_resolver_iterator/iterator_category.html迭代器类别是前向迭代器 http://en.cppreference.com/w/cpp/concept/ForwardIterator。前向迭代器具有“多次传递保证”,允许重复取消引用迭代器的副本,产生相同的结果。
所以,我们已经完成了一半:保留迭代器仍然可以。然而,当然,就像任何其他[前向]迭代器一样,我们必须考虑迭代器失效 https://stackoverflow.com/questions/16904454/what-is-iterator-invalidation.
所以,真正的问题归结为:解析器迭代器何时失效.
我们知道什么?
用例resolve
函数满足的是联系。对于连接而言,第一个有效的端点就足够了,因此不需要实际保留列表。
本着按需付费的精神,解析器将状态保持的时间超过所需的时间是没有意义的。另一方面,如果不支持 Multipass,则迭代器位于 ForwardIterator 类别中是没有意义的。
文档什么也没说。我们只有一个办法:深入代码
深入研究代码
我们发现了一些表面之下的步骤:asio/detail/resolver_service.hpp:73 https://github.com/boostorg/asio/blob/boost-1.65.1/include/boost/asio/detail/resolver_service.hpp#L73
// Asynchronously resolve a query to a list of entries.
template <typename Handler>
void async_resolve(implementation_type& impl,
const query_type& query, Handler& handler)
{
// Allocate and construct an operation to wrap the handler.
typedef resolve_op<Protocol, Handler> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
boost_asio_handler_alloc_helpers::allocate(
sizeof(op), handler), 0 };
resolve_op
显示迭代器是使用创建的basic_resolver_iterator.hpp::创建 https://github.com/boostorg/asio/blob/boost-1.65.1/include/boost/asio/ip/basic_resolver_iterator.hpp#L76
这给我们带来了答案:line 251 https://github.com/boostorg/asio/blob/boost-1.65.1/include/boost/asio/ip/basic_resolver_iterator.hpp#L251
typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type;
boost::asio::detail::shared_ptr<values_type> values_;
std::size_t index_;
因此,只要您保留有效迭代器(而不是最终迭代器)的副本,您就可以继续取消引用它。它甚至会保留查询参数的副本(host_name
and service_name
)与每个解析器条目。这看起来有点浪费,但我想在设计缓存方案时可能会派上用场。
总结:
-
Q.解析器迭代器何时失效?
-
A.当有效迭代器的最后一个副本被破坏时。
这意味着“它们始终保持有效”(如果它们曾经有效)。
与例如相反输入迭代器
² 一般来说,C++ 实现遵循
零开销原则:你不使用的东西,你就不需要付费 [C++ 的设计和演化,1994]