将 std::iter_swap 用于 std::optional
Posted
技术标签:
【中文标题】将 std::iter_swap 用于 std::optional【英文标题】:Using std::iter_swap for std::optional 【发布时间】:2015-08-11 11:10:10 【问题描述】:看着std::iter_swap
reference我的结论是:
struct A ;
std::experimental::optional< A > xA, yA;
std::iter_swap(x, y);
是合法的。是这样吗?
要求参数是 ForwardIterator 意味着它们应该满足一个要求:在取消引用(迭代器)后传递的对象应该保持有效(可取消引用?)状态。理解对了吗?
【问题讨论】:
概念前向迭代器为:en.cppreference.com/w/cpp/concept/ForwardIterator ForwardIterator 除了你提到的,还有很多要求。 @ForEveR 我读到了。可以违反对引用类型和迭代器本身的哪些要求?我认为std::iter_swap
的引用可能已经过时,因为std::optional
等新容器的存在。
optional
s 可能为空。 iter_swap
实现将在这样的空 optional
s 上中断。 swap(optional, optional)
处理空的和完整的选项。我不明白这一点?
@Yakk 上面的代码清楚地显示了非空选项。无效和过去的迭代器也不能取消引用。无论如何,请参阅下面的答案和讨论。
【参考方案1】:
ForwardIterator concept 比你说的更受限制。 您的示例仅在使用类似此实现的情况下才有效:
template<class ForwardIt1, class ForwardIt2>
void iter_swap(ForwardIt1 a, ForwardIt2 b)
using std::swap;
swap(*a, *b);
但由于不能保证您实际上不应该使用iter_swap
作为可选。你真的应该使用swap for optional
【讨论】:
好的,iter_swap
的实现可以按值传递参数(迭代器),但不能传递引用。这里很重要。
@Orient iter_swap
的签名清楚地表明它按值接受参数。这里没有空间让实现做任何其他事情。
不想问另一个问题,但是std::shared_ptr
呢?智能指针还是迭代器?
它们应该被取消引用到std::iter_swap
并且可以。在这种情况下可能会违反哪些 ForwardIterator 不变量?
@Orient 什么是例如类型std::iterator_traits<std::shared_ptr<T> >::reference
?以上是关于将 std::iter_swap 用于 std::optional的主要内容,如果未能解决你的问题,请参考以下文章
如何将 std::ratio 用于大于 int64_t 的值?
没有可行的重载'='用于将std :: function回调赋值为成员函数
似乎我不能将 MS 检漏仪用于新表达式“new (std::nothrow)”。那是对的吗?