考虑以下insert
和emplace
成员函数std::vector<T>
:
template <class... Args> iterator emplace(const_iterator position, Args&&... args);
iterator insert(const_iterator position, const T& x);
iterator insert(const_iterator position, T&& x);
iterator insert(const_iterator position, size_type n, const T& x);
Run Code Online (Sandbox Code Playgroud)
如果通过引用向量本身的元素作为参数来调用其中一个,该怎么办?通常,它们中的每一个都会使对所有元素的引用无效,这些元素position
可能包括参数,或者如果发生重新分配,则引用所有元素,这肯定包含它,但这是否意味着这样的调用无效或插入(似乎先发生?
查看一些常见的实现会产生奇怪的结果:
libstdc ++在移动任何元素之前复制参数,但仅在const T&
重载中insert
.它包含这个评论:
这三个操作的顺序由C++ 0x情况决定,其中移动可以改变属于现有向量的新元素.这只是调用者通过const lvalue ref获取元素的问题(见23.1/13).
但是C++11§23.1只是容器库的简短摘要,即使我们假设这是指§23.2.1(以前是C++ 03中的§23.1),仅仅是§23.2.1/ 13给出了分配器感知容器的定义,这似乎与此无关.我已经看了第23章,但我没有找到任何相关的东西.
libc ++在移动任何元素之前创建一个临时元素emplace
,而在insert
其中首先移动元素但将参数引用转换为指针并调整它以确保它指向原始元素 - 但同样,它仅在const T&
重载中完成所有这些操作.
在所有情况下移动任何元素之前,Visual C++会创建一个副本/临时文件.
我错过了标准定义此行为的地方吗?为什么我看到的三个C++库彼此不一致?为什么libstdc ++评论说它只是一个问题insert(const_iterator, const T&)
?如果标准不要求这个工作,为什么图书馆总是懒得让它工作呢?(当然这会花费一些本来可以避免的副本和/或移动.)最后,如果我正在实现一个类似的容器,std::vector
我应该让它工作吗?
C99附件F(IEEE浮点支持)说:
pow(??, y)
y> 0时返回+∞而不是奇数.
但是,比方说,( - ∞)0.5实际上有虚数值±∞i,而不是+∞.C99自己sqrt(??)
返回NaN并按预期生成域错误.为什么然后pow
需要返回+∞?
(大多数其他语言直接使用C库,或者像本例中的Python一样,通过标准复制它所需的行为,因此在实践中这不仅仅影响C99.)
该Set
接口不承诺实现是否允许null
元素.每个实现都应该在其文档中声明.
Collectors.toSet()
承诺回报的实现Set
,但明确地让"无担保的类型,可变性,串行化,或线程安全Set
返回".没有提到空安全性.
目前执行Collectors.toSet()
中的OpenJDK总是使用HashSet
,允许null元素,但是这可能在未来改变和其他实施方式可以做出不同的.
如果某个Set
实现禁止null
元素,它会NullPointerException
在不同时间抛出,特别是在尝试时add(null)
.似乎如果Collectors.toSet()
决定使用null不容忍的Set
实现,则调用stream.collect(Collectors.toSet())
一个Stream stream
将抛出.规范collect
没有列出任何异常,也没有列出任何Collector
方法的规范.这可能表明该collect
调用允许空值stream
,但另一方面,目前尚不清楚这是否实际上意味着很多,因为NullPointerException
未经检查的异常并不严格必须列出.
在其他任何地方都明确指出了吗?特别是,以下代码保证不抛出?它有保证返回true
吗?
import java.util.stream.*;
class Test {
public static boolean setContainsNull() {
return Stream.of("A", "list", "of", null, "strings")
.collect(Collectors.toSet())
.contains(null);
}
}
Run Code Online (Sandbox Code Playgroud)
如果没有,那么我假设在使用Collectors.toSet()
或准备好处理之前我们应该始终确保流不包含空值NullPointerException
.(这是例外单独够有关系吗?)或者,当这是不可接受的或硬的,我们可以要求使用类似的代码一组特定的实现Collectors.toCollection(HashSet::new)
.
编辑:有一个现有的问题,听起来表面上相似,这个问题被关闭作为一个假设的副本.但是,相关问题根本没有解决Collectors.toSet()
.此外,该问题的答案构成了我的问题的 …
C++ 11(和C++ 14)STL容器具有noexcept
析构函数和clear()
成员函数.
这意味着元素也应该具有noexcept
析构函数,或者至少存储在容器中的实际元素在销毁时不应抛出任何异常 - 或者更准确地说,相应的allocator_traits<Allocator>::destroy
调用不应抛出.
这是否在标准的任何地方指定为要求(明确或暗示另一个明确要求)?如果没有,为什么?
我知道is_nothrow_constructible
需要一个noexcept
析构函数,但is_constructible
单独没有,并且容器需求是根据概念而不是类型特征模板指定的.
C++标准(从C++ 11到当前的C++ 17草案的所有方式)在[rand.eng.lcong]中说明如下:
Run Code Online (Sandbox Code Playgroud)template<class Sseq> explicit linear_congruential_engine(Sseq& q);
效果:构造一个
linear_congruential_engine
对象.与ķ =⌈log 2(米)÷32⌉和一个长度的阵列32(或等效物)ķ + 3,调用q.generate(a + 0, a + k + 3)
,然后计算小号 =(Σ Ĵ = 0 ķ -1 一个Ĵ 3 ·2 32 Ĵ)mod m.如果c mod m为0且S为0,则将引擎状态设置为1,否则将引擎状态设置为S.
为什么一个0,一个1和一个2丢弃?