使用一个元素处理单个对象(如数组),采用一个结束指针

时间:2014-01-28 16:21:46

标签: c++ c++11 language-lawyer

序言:众所周知,将指针放在数组末尾之后是合法且明确定义的:

int main()
{
  int na [1] = {};
  const int* naBegin = na;
  const int* naEnd = na + 1; // one-past-end, OK  
}

此指针可用于比较,这有助于C样式数组(或更准确地说,其中的指针)与采用迭代器的标准库例程兼容,例如copyLive Demo ):

template <typename Field, typename Iter>
void foo(Iter begin, Iter end)
{
  std::copy (begin, end, std::ostream_iterator <Field> (std::cout, std::endl);
}
int main()
{
  int na [1] = {};
  foo <int> (na, na + 1);
}

标准(C ++ 03参考)支持其合法性和定义性:

5.7添加运算符

  

5 /当添加或减去具有整数类型的表达式时   从指针开始,结果具有指针操作数的类型。如果   指针操作数指向数组对象的元素和数组   足够大,结果指向一个偏离的元素   原始元素使得下标的差异   结果和原始数组元素等于整数表达式。   换句话说,如果表达式P指向一个的第i个元素   数组对象,表达式(P)+ N(等效地,N +(P))和(P)-N   (其中N具有值n)分别指向第i + n和第i   数组对象的第i个元素,只要它们存在即可。而且,如果   表达式P指向数组对象的最后一个元素,   表达式(P)+1指向数组对象的最后一个元素,   如果表达式Q指向一个数组的最后一个元素   对象,表达式(Q)-1指向数组的最后一个元素   object。如果指针操作数和结果都指向元素   相同的数组对象,或一个超过数组的最后一个元素   对象,评估不得产生溢出;否则,   行为未定义。

当我在标准中查看对过去指针的浊度的引用时,我发现的每个引用都在讨论数组。如果我们试图将对象的地址过去,而不是数组呢?


问题:是否可以将单个对象视为未分配为数组,就像它是一个数组并采取有效的一个 - 过去 - 所述对象的结束地址?

例如(Live Demo):

#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <iterator>

template <typename Field, typename Iter>
void foo(Iter begin, Iter end)
{
  std::copy (begin, end, std::ostream_iterator <Field> (std::cout, "\n"));
}
int main()
{
  int na = 42;
  foo <int> (&na, &na + 1);
}

此代码是否合法且标准定义明确?

1 个答案:

答案 0 :(得分:10)

答案在您引用的段落之前的段落中:

  

4 /为了这些运算符的目的,指向非阵列对象的指针与指向长度为1的数组的第一个元素的指针的行为相同,其中对象的类型为其元素类型。

(注意:我引用的是C ++ 11,因为我手头没有C ++ 03.我很确定没有任何改变。)

所以是的,&na + 1是一个有效的过去指针。