It may help if you compare const char** glfwExtensions;
with the famous variable argv
in main
:
int main(int argc, char **argv) // or: char *argv[]
glfwExtensions
can likewise be seen as an array of const char*
So, after
glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
you can therefore
for(uint32_t i = 0; i < glfwExtensionCount; ++i) {
// access glfwExtensions[i] here
// or *(glfwExtensions + i) (same thing)
}
Since glfwExtensions
is a const char**
, then glfwExtensions + i
is also a const char**
, i
steps from glfwExtensions + 0
.
The asterisk in *(glfwExtensions + i)
means that you dereference the pointer to get a reference to the value it's pointing at - which, since you have a const char**
, is a const char*
.
glfwExtensions
is a pointer to the first element in glfwExtensionCount
number of elements and you can use glfwExtensions + i
to get a pointer to any of those elements.
The line you wonder about
std::vector<const char*> extensions(glfwExtensions,
glfwExtensions + glfwExtensionCount);
is using the vector
constructor that takes two iterators and populates the vector
with the dereferenced values, the actual const char*
s.
glfwExtensions + glfwExtensionCount
is pointing one element past the last element. You are only allowed to deference the elements in the range [glfwExtensions + 0, glfwExtensions + glfwExtensionCount - 1]
so this pointer is used to tell the vector
where to stop reading values.
It's similar to doing this:
const char** current = glfwExtensions;
const char** one_past_last = glfwExtensions + glfwExtensionCount;
std::vector<const char*> extensions;
extensions.reserve(std::distance(current, one_past_last));
for(;current != one_past_last; ++current) // stop at one_past_last
// dereference current to get the value it is pointing at:
extensions.push_back(*current);