理解std::copy:简易double型vector拷贝构造函数的范围疑问
Great question—let’s break down why that range works, and when you might want to tweak it for better clarity.
First, let’s assume your custom vector implementation looks roughly like this (the minimal context to make sense of the copy constructor):
#include <algorithm> // For std::copy class SimpleDoubleVector { private: double* elem; // Pointer to the underlying array of doubles int sz; // Number of elements stored in the vector public: // Copy constructor in question SimpleDoubleVector(const SimpleDoubleVector& arg) : sz(arg.sz), elem(new double[arg.sz]) // Initialize size first! { // The range you're asking about: arg.elem, arg.elem + sz std::copy(arg.elem, arg.elem + sz, elem); } // Other required members (destructor, assignment operator, etc.) omitted for brevity };
Why arg.elem, arg.elem + sz is correct here
In C++, the constructor initialization list runs before the constructor body. That means by the time we get to the std::copy line, our new vector’s sz member has already been set to match arg.sz (the size of the vector we’re copying from).
STL algorithms like std::copy rely on a half-open interval [first, last)—they copy every element starting at first up to (but not including) last. Here, arg.elem + sz is exactly equivalent to arg.elem + arg.sz, which points one past the last element of the source vector. This tells std::copy to copy all sz elements from the source into our new array—exactly what a copy constructor needs to do.
When it might feel confusing (and a clearer alternative)
The confusion usually stems from wondering if sz refers to the new vector’s size or the source’s. While the original code is technically correct, it’s more readable to explicitly use arg.sz instead of sz in the range:
std::copy(arg.elem, arg.elem + arg.sz, elem);
This removes any ambiguity for future readers (including your future self) about which size we’re using. Both versions behave identically, but the explicit one is harder to misinterpret.
What would make the range incorrect?
If the initialization list didn’t set sz to arg.sz first—for example, if sz was initialized to 0 or a random value—then arg.elem + sz would point to the wrong place. That could lead to copying too few elements, or accessing memory outside the source vector’s bounds. But in the standard copy constructor pattern for a simple vector like this, the initialization list correctly syncs sz with the source, so the range is safe.
内容的提问来源于stack exchange,提问作者TosinAl

