I don't quite understand what the following does:
std::vector<const char*> getRequiredExtensions()
{
uint32_t glfwExtensionCount = 0;
const char** glfwExtensions;
glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
std::vector<const char*> extensions(glfwExtensions, glfwExtensions glfwExtensionCount);
if (enableValidationLayers) {
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
}
return extensions;
}
I don't understand this line:
std::vector<const char*> extensions(glfwExtensions, glfwExtensions glfwExtensionCount);
What exactly does it do? And what does glfwExtensions resolve to, I only get that it's a double pointer (Which is also a new concept for me). And what does the glfwExtensions glfwExtensionCount mean?
thanks for any help!
CodePudding user response:
Let's concentrate on the following line of code:
std::vector<const char*> extensions(glfwExtensions, glfwExtensions glfwExtensionCount);
This declares extensions
as a variable of the templated std::vector<typename T>
type, where the T
type resolves to const char*
(that is, it declares a vector whose elements are each pointers to constant character data). This vector object is initialized using the constructor that takes two iterator arguments – the form (5) on this cppreference page.
A point of confusion here may be how the arguments are iterators: well, pointers are also iterators (in many ways). In this case, the const char** glfwExtensions;
line declares a variable that points to a const char*
(which is the type of the vector's elements), and the call to glfwGetRequiredInstanceExtensions
makes this point to the beginning of an array of such (const char*
) pointers and sets the glfwExtensionCount
variable to the number of elements in that array. Further, adding the size of an array to a pointer to its first elements yields a pointer to "one past the end" of the array – which is equivalent to an STL "end" iterator.
Thus, the two arguments to the constructor are, effectively, acting as std::begin(glfwExtensions)
and std::end(glfwExtensions)
– but those functions can't be used directly, because glfwExtensions
is not an array of known size in this context.
CodePudding user response:
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);
CodePudding user response:
So...
const char** glfwExtensions;
It is a pointer to a pointer (pointer to string) This mean that when you to this...
glfwExtensions glfwExtensionCount
The: const char** glfwExtensions; is like a vector and with count you access its next element.
To simplify the: glfwExtensions glfwExtensionCount is like vector::at(glfwExtensionCount)
And basicly in this code:
std::vector<const char*> extensions(glfwExtensions, glfwExtensions glfwExtensionCount);
You are creating std::vector from begin which is glfwExtensions to end which is glfwExtensions glfwExtensionCount