背景
在 C++11 中,基于范围的 for 循环处理此处概述的三种“范围” (链接)。我在下面引用了相关部分。
句法
for (range_declaration : range_expression) loop_statement
解释
上面的语法产生类似于以下的代码(
__range
,__begin
并且__end
仅用于说明):{ auto && __range = range_expression; for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) { range_declaration = *__begin; loop_statement } }
被
range_expression
评估以确定将被迭代的序列或范围。序列的每个元素都被取消引用,并使用range_declaration
.和
begin_expr
被end_expr
定义为:
- If
(__range)
是一个数组,那么(__range)
and(__range + __bound)
,__bound
数组绑定在哪里;- 如果
(__range)
是一个类并且有一个开始或结束成员(或两者都有),那么begin_expr
is__range.begin()
和end_expr
is__range.end()
;- 否则,
begin(__range)
和end(__range)
,它们是基于与参数相关的查找规则找到的,并std
作为关联的命名空间。
问题
我应该如何编写一个具有三个特化的模板函数来处理引用的项目符号列表中完全相同的三个案例?
我正在考虑以下内容,但我不确定如何正确执行此操作。
//Handle third bullet - default case
template <typename Range>
void f(Range& range)
{
for (auto it = begin(range); it != end(range); ++it)
{
T& item = *it;
/* do something custom with item */
}
}
//Handle first bullet - "range" is an array
template <>
void f<T[]>(T[] range)
{
auto end = range + sizeof(range)/sizeof(*range);
for (auto it = range; it != end; ++it)
{
T& item = *it;
/* do something custom with item */
}
}
//Handle second bullet - "range" with "begin" and/or "end" function
template <>
void f<RangeBE>(RangeBE& range)
{
//Somehow restrict type RangeBE to classes that have
//begin or end member functions...
//Can enable_if be used for this?
for (auto it = range.begin(); it != range.end(); ++it)
{
T& item = *it;
/* do something custom with item */
}
}
我完全错误地接近这个吗?这甚至可以用 C++11 做吗(即编译器是否需要做一些特殊的事情来完成这种专业化)?请赐教。:)
一些澄清...
我的问题是如何处理所有三种可能类型的“范围”(来自引用的项目符号列表)作为我编写的函数的输入。(我将使用这里获得的知识来实际编写一个template <typename Range>
以相同方式限定的类,其中该类具有处理所有三种类型范围的专业化。)
我的问题不是如何编写一个满足三种可能的“范围”类型之一的类(来自引用的项目符号列表)。有多个关于此的 SO 问题 - 这不是这些问题的重复。
我的问题不是如何使用基于范围的 for 循环。
“仅在“中使用基于范围的 for 循环f
”不是一个选项或答案。我实际上想要做的是模仿基于范围的 for 循环的语义,但是由于这个问题范围之外的复杂性,我不能简单地在示例函数中使用基于范围的 for 循环f
。请接受这样一个事实,即我有充分的理由不“只使用基于范围的 for 循环”。解释原因太复杂了。