将 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 等新容器的存在。 optionals 可能为空。 iter_swap 实现将在这样的空 optionals 上中断。 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&lt;std::shared_ptr&lt;T&gt; &gt;::reference?

以上是关于将 std::iter_swap 用于 std::optional的主要内容,如果未能解决你的问题,请参考以下文章

如何将 std::ratio 用于大于 int64_t 的值?

没有可行的重载'='用于将std :: function回调赋值为成员函数

似乎我不能将 MS 检漏仪用于新表达式“new (std::nothrow)”。那是对的吗?

将 const std::unique_ptr 用于 pimpl 习惯用法

如何将 std::string 转换为 WCHAR

std :: vector是否将其值类型的赋值运算符用于push_back元素?