做,至少在使用时最清晰的方式,这是你的类型标记的特殊迭代的目的。
首先,一些机械:
template<class Mark, class T>
struct marked_type {
T raw;
marked_type(T&& in):raw(std::forward<T>(in)) {}
};
template<typename Mark, typename T>
marked_type<Mark, T> mark_type(T&& t) {
return {std::forward<T>(t)};
}
接下来,我们发明一个标志,上面写着 “迭代奇怪”,和过载开始/结束:
struct strange_iteration {};
template<typename T>
auto begin(marked_type<strange_iteration, T> const& container)
-> decltype(std::begin(std::forward<T>(container.raw)))
{
std::cout << "BEGIN";
using std::begin;
return begin(std::forward<T>(container.raw));
}
template<typename T>
auto end(marked_type<strange_iteration, T> const& container)
-> decltype(std::end(std::forward<T>(container.raw)))
{
std::cout << "END";
using std::end;
return end(std::forward<T>(container.raw));
}
,然后在使用点:
std::string s = "hello world";
for(char c : mark_type<strange_iteration>(s)) {
std::cout << c;
}
std::cout << "\n";
与一个说明我写mark_type
是过分通用的。
现在,mark_type<Foo>
将创建左值的引用,并创建右值的移动副本(如果传递给它)。在迭代中,其返回值的生命周期将通过引用生命周期扩展进行扩展。
您可以使用此技术做的事情一样
for(char c : mark_type<reverse_iteration>(s))
现在在哪里,我们不是重复倒退,无论我们在通过容器。在“副本创建”为右值是需要同样的结构这个:
for(char c: mark_type<reverse_iteration>(mark_type<strange_iteration>(s))
我们在哪里菊花链的标记。生命周期扩展只适用于最外层的返回值,我们在右值的“创建副本和移动”基本上是手动生存期延长。
最后,在上面的代码中使用std::begin
最好在返回值的ADL允许上下文中完成。创建一个辅助命名空间是这样的:
namespace adl_helper {
using std::begin; using std::end;
template<typename T>
auto adl_begin(T&& t)->decltype(begin(std::forward<T>(t))); // no implementation
template<typename T>
auto adl_end(T&& t)->decltype(end(std::forward<T>(t))); // no implementation
// add adl_cbegin, adl_rbegin etc in C++14
}
然后用adl_helper::adl_begin
替换decltype
小号std::begin
在我上面的代码,它模拟for(a:b)
回路是如何找到begin
和end
触摸更好的(不完美,但更好)。
C++ 1y可能会附带一些机制来消除对上述黑客的需求。
示例代码运行:http://ideone.com/RYvzD0
注:您的基本假设是错误的:没有ADL这里涉及到,'s'是'的std :: string'所以'为(字符C:S)'的行为就像使用_member_形式's.begin()'和's.end()',而不是非成员形式'begin(s)'和'end(s)'(参见remyabel的回答) –
@gx_ yes ,下面的一些答案提到了这一点。我把它颠倒过来,认为非成员'begin'首先尝试,成员'begin'第二。 – uk4321
@ uk4321你可能感兴趣的[n3257](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3257.pdf)。 – 2013-12-24 00:24:25