上C++最流行的交迭代器失效规则声称,目前还不清楚,如果在过去的最端迭代器(即,那些由返回end(),cend(),rend(),和crend())根据相同的规则正常迭代器,这点在元件被无效容器.这些针对2003和2011 C++的声明,推迟到讨论End迭代器失效规则的帖子,其中接受的答案表明2003标准在这个问题上是模棱两可的.这一结论是基于23.1/10评论(在的情况下swap(),这似乎暗示,当规范没有明确提及过去的最末端迭代器失效,他们可能会失效).
对该帖子的问题的评论(由mike-seymour提出)表明C++ 11在这个问题上是明确的,在deques 的情况下.我的问题是关于所有容器:
换句话说,
C++ 11引入了一个名为的对象std::ignore:
const /* unspecified */ ignore;
Run Code Online (Sandbox Code Playgroud)
为简洁起见,让我们
typedef decltype(std::ignore) T;
Run Code Online (Sandbox Code Playgroud)
据我所知,由于[C++ 11,20.4.2.4:7] 的规范,唯一的要求T就是它.CopyAssignablestd::tie
在g ++ - 4.8中,我发现T另外DefaultConstructible(例如,T x;编译).这是实现定义的行为吗?
(如果T我有其他要求,请详细说明.)
C++要求OutputIterator类型X支持表单的表达式r++,其中r是一个实例X.此后缀增量必须在语义上等效于:
(*) { X tmp = r; ++r; return tmp; }
并且必须返回可转换为的类型X const&.在C++ 11中,请参见24.2.4(但这不是新的).它说,在同一部分
输出迭代器上的算法绝不应该尝试两次通过相同的迭代器.它们应该是单通道算法.
给出(*),上面说我复制返回值就像 X a(r++);
假设r在递增之前是dereferencable,但没有取消引用.它是否需要a被取消参考?如果是这样,必须X a(r++); *a = t;执行相同的任务*r++ = t;吗?是否有任何(其他)条件a和r?
否则,假设r在递增之前被解除引用/分配,并且其递增的值(也)是不可引用的.以下哪一项(如果有的话)定义明确:(a)
*a = t;,(b)++a; *a = t;,(c)*r = t;?
另请参阅后续操作:取消引用 - 分配给双倍增量的OutputIterator
进一步满足输出迭代器要求的迭代器称为可变迭代器.不可变迭代器称为常量迭代器.[24.2.1:4]
这表明你可以有一个可变的输入迭代器,它满足输入和输出迭代器的要求.
在递增输入迭代器之后,其旧值的副本不必是可解除引用的[24.2.3].但是,标准对输出迭代器并没有相同的说法; 实际上,后缀增量的操作语义给出为{ X tmp = r; ++r; return tmp; },表明输出迭代器可能不会使旧迭代器值无效(副本).
那么,可以递增一个可变输入迭代器使旧迭代器副本无效吗?
如果是这样,你将如何支持这样的代码X a(r++); *a = t或X::reference p(*r++); p = t用(例如)代理对象?
如果没有,那为什么boost::iterator声称它需要一个代理对象?(链接是代码;向下滚动以阅读structs 上的注释writable_postfix_increment_proxy和postfix_increment_result).也就是说,如果您可以返回旧迭代器值的(可解除引用的)副本,为什么还需要将此副本包装在代理中?
您可以使用C++ 11可变参数模板来完成/* ??? */:
template<bool...v> struct var_and { static bool constexpr value = /* ??? */; };
Run Code Online (Sandbox Code Playgroud)
所以在编译时var_and<v...>::value提供&&了布尔包v?
你可以做同样struct var_or<v...>的||?
你能用短路评估(两种情况下)吗?
template<bool... v> constexpr bool var_and = (v && ...);
template<bool... v> constexpr bool var_or = (v || ...);
Run Code Online (Sandbox Code Playgroud)
看来,对于基于参数包的方法,只能进行受限类型的"短路评估":在var_or<true,foo(),bar()>仅实例化一次调用||时,它也会调用两者foo和bar.
可能重复:
括号可以将任意标识符作为参数吗?C++
我的问题是关于使用参数包'unpack'运算符,....下面的代码片段在g ++ 4.7.1中给出了编译器错误(在'...'之前的预期参数包,在最后一行),我想知道为什么.
template<class T> struct type_wrapper
{ typedef T type; };
template<class...Ts> struct variadic_wrapper { };
// This compiles:
template<class...Ts> struct variadic_type_wrapper
{ typedef variadic_wrapper<typename type_wrapper<Ts>::type...> type; };
// Parentheses screw it up:
// Error: expected parameter pack before '...'
template<class...Ts> struct variadic_type_wrapper
{ typedef variadic_wrapper<(typename type_wrapper<Ts>::type)...> type; };
Run Code Online (Sandbox Code Playgroud)
表达式(...)隐藏了底层类型的arity吗?谢谢你清理这个!