次のコードを検討してください。
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
string myAry[] =
{
"Mary",
"had",
"a",
"Little",
"Lamb"
};
const size_t numStrs = sizeof(myStr)/sizeof(myAry[0]);
vector<string> myVec(&myAry[0], &myAry[numStrs]);
copy( myVec.begin(), myVec.end(), ostream_iterator<string>(cout, " "));
return 0;
}
ここで興味深いのは&myAry[numStrs]
、numStrs が 5 に等しいため、&myAry[numStrs]
存在しないものを指しているということです。配列の6 番目の要素。上記のコードには、この別の例があります: myVec.end()
は、 vector の 1 つ後ろの端を指しmyVec
ます。存在しないこの要素のアドレスを取得することは完全に合法です。のサイズがstring
わかるので、s の C スタイル配列の 6 番目の要素のアドレスがどこをstring
指す必要があるかがわかります。このポインターを評価するだけで、逆参照しない限り、問題ありません。等しいかどうかを他のポインターと比較することもできます。STL は、一連の反復子に作用するアルゴリズムで常にこれを行います。イテレータはend()
最後を超えてポイントし、ループは counter の間ループし続けます!= end()
。
だから今これを考えてみましょう:
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
string myStr = "Mary";
string* myPtr = &myStr;
vector<string> myVec2(myPtr, &myPtr[1]);
copy( myVec2.begin(), myVec2.end(), ostream_iterator<string>(cout, " "));
return 0;
}
このコードは合法で明確に定義されていますか? のように、配列要素のアドレスを最後を超えて取得することは合法であり、明確に定義されてい&myAry[numStrs]
ますmyPtr
。