我已经写了一些功能与原型是这样的:

template <typename input_iterator>
int parse_integer(input_iterator &begin, input_iterator end);

的想法是,主叫方会提供一定范围的字符,并且该函数将解释字符作为一个整数值,并返回它,留下开始在一个过去上次使用的字符。例如:

std::string sample_text("123 foo bar");
std::string::const_iterator p(sample_text.begin());
std::string::const_iterator end(sample_text.end());
int i = parse_integer(p, end);

这将留下i为123,p “指点” 在foo之前的空间中。

因为我已经被告知(不解释),它是坏的形式通过引用传递一个迭代器。它是不好的形式?如果是这样,为什么?

有帮助吗?

解决方案

有什么真的错了,但它肯定会限制使用的模板。你不能只是把有else或类似v.begin()产生一些返回的迭代器,因为这些将是临时工。你将永远首先必须使本地副本,这是某种形式的样板不是真的不错的。

的一种方式是重载它:

int parse_integer(input_iterator begin, input_iterator end, 
                  input_iterator &newbegin);

template<typename input_iterator>
int parse_integer(input_iterator begin, input_iterator end) {
    return parse_integer(begin, end, begin);
} 

另一种选择是具有输出迭代器,其中数字将被写入:

template<typename input_iterator, typename output_iterator>
input_iterator parse_integer(input_iterator begin, input_iterator end,
                             output_iterator out);

您将有返回值,返回新的输入迭代器。并且可以接着使用插入器迭代把解析号码到载体或指针把它们直接放入一个整数或其阵列如果你已经知道数的量。

int i;
b = parse_integer(b, end, &i);

std::vector<int> numbers;
b = parse_integer(b, end, std::back_inserter(numbers));

其他提示

<强>一般来说:

如果你传递非const参考,呼叫者不知道如果迭代被修改。

您可以传递一个参考const,但通常迭代器是足够小,它给出了通过由值没有优势。

<强>你的情况:

我不认为有什么不对,你做什么,但它不是太关于迭代器使用标准式的。

当他们说“不按引用传递”也许这是因为它是比较正常的/地道通过迭代器的值参数,而不是通过const引用传递他们:你做到了,第二个参数

在本实施例中,但是你需要返回两个值:解析的int值,并且,新的/修改的迭代器值;和给定的一个功能不能有两个返回代码,编码的返回码中的一个作为一个非const引用是IMO正常。

另一种方法是向编码它是这样的:

//Comment: the return code is a pair of values, i.e. the parsed int and etc ...
pair<int, input_iterator> parse(input_iterator start, input_iterator end)
{
}

在我看来,如果你想这样做的参数应该是一个指针,你会改变迭代器。我不是非const引用参数的大风扇,因为他们隐瞒事实,传递的参数可能会改变。我知道有很多谁与我对这个观点C ++的用户 - 这很好

然而,在这种情况下,它的所以常见的迭代器被视为值参数,我认为这是一个特别坏主意由非const引用传递迭代器和修改通过迭代器。它只是靠在惯用方式迭代器通常使用。

既然有一个伟大的方式做你想做的是没有这个问题的,我认为你应该使用它:

template <typename input_iterator>
int parse_integer(input_iterator* begin, input_iterator end);

现在呼叫者必须做的:

int i = parse_integer(&p, end);

和它会显而易见的是,迭代器可以改变的。

顺便说一句,我也很喜欢 litb的建议返回新的迭代器,并把所解析的值代入由输出迭代器指定的位置的

在这种情况下,我认为通过引用传递一个迭代是完全合理的,只要它是良好的记录。

这是值得注意的是,你的方法(通过引用传递一个迭代器来跟踪你是一个标记化流时,其中的)正是被采取的升压::标记生成器。特别是看到 TokenizerFunction概念的定义。总的来说,我觉得提高::标记生成器被设计得相当不错,并经过深思熟虑的。

我觉得标准库算法按值传递的迭代器专(现在有人将发布一个明显的例外) - 这或许是思想的起源。当然,没有什么表示,自己的代码有看起来像标准库!

您的函数声明的第二个参数丢失的基准,是吗?

不管怎样,回到你的问题:没有,我没有读过什么,说你不应该通过引用传递迭代器。与引用的问题是,它们允许你改变引用的对象。在这种情况下,如果你改变迭代,则潜在地拧向上超出该点从而使得进一步处理不可能的整个序列。

只是一个建议:仔细输入您的参数

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top