Reputation: 5034
I am new to C++ templates and encountered these C++ templates related codes but is not able to understand their meaning:
class StringBuffer
{
CharBuffer cb;
..
template <size_t ArrayLength>
bool append(const char (&array)[ArrayLength]) {
return cb.append(array, array + ArrayLength - 1); /* No trailing '\0'. */
}
};
What does the bool append(const char (&array)[ArrayLength]) mean? It seems to me that the function template will be instantiated to something taking a parameter with a specific ArrayLength. But isn't that we cannot specify an array length in the parameter list of a function? Also what does const char (&array) mean? Shouldn't it be something like const char &(without the parentheses)?
I am reading the book C++ Templates The Complete Guide by David Vandevoorde/Nicolai M.Josuttis, which part of the book covers the above syntax?
Upvotes: 3
Views: 185
Reputation:
The given code is a good lesson: at first , It want to pass a array , So can't pass by value, then pass by refrence (&) , Then it pass it by const word that safe pass it. You know C/C++ has limitation in array, So programmer of this code defined a template for length of Array, and solve this problem.
Upvotes: 0
Reputation: 1
This syntax will set a template parameter based on the size of a statically allocated array argument.
The templated version of "append" (that you included) calls an overload which takes 2 arguments: a pointer to char and a count (you did not include this).
So you might have an array like:
const char my_string[] = "hi";
You would use the "append" member function like this:
my_string_buffer_object.append(my_string);
And the length of my_string will be auto-detected, setting the ArrayLength parameter to the length of my_string. Then a more verbose version of "append" is called with the string length automatically filled in for you.
Basically, this version of "accept" wraps another version. It lets you pass an array as the only argument, automatically filling in a length using the template parameter's info.
If you use this syntax, keep in mind that these array length parameters count elements and not object sizes (what sizeof would tell you about the array). For char these are the same, but arrays with larger-sized element types will produce a template array length parameter smaller than its sizeof.
Upvotes: 0
Reputation: 254441
const char (&array)[ArrayLength]
is a reference to an array of ArrayLength
objects of type char
.
Without the parentheses, it would be an array of references, which is not allowed. Without the &
, it would be an array which (as a function parameter) decays to a pointer, losing the information about the size of the array.
It seems to me that the function template will be instantiated to something taking a parameter with a specific ArrayLength.
That's right. The array length is known at compile time, and this will instantiate a function that can use that compile-time value.
But isn't that we cannot specify an array length in the parameter list of a function?
Yes, you could supply the length as an extra function parameter; but that would be a runtime value, and there'd be know way to validate that it was correct. The template ensures that the template argument really is the size of the array.
which part of the book covers the above syntax?
I don't have that book but, looking at the table of contents I'd suggest looking at 4.2 (Nontype Function Template Parameters) and 11 (Template Argument Deduction) for this kind of thing.
Upvotes: 2
Reputation: 55395
It's the syntax for passing the array by reference (since arrays can't be passed by value in C++):
void foo(const char (&array)[10]) { ... } // We can pass an array of lenth 10
Now throw a template parameter in the mix instead of the 10. The compiler knows the size of an array at compile time and can instantiate the template with correct value.
template<size_t N>
void foo(const char (&array)[N])
{
// use N, it'll be whatever the size of the array you instantiate the template with is
}
Upvotes: 2
Reputation: 11736
It means "reference to const char array". The reason for it is that if you pass like
template <int S>
void f(T a[s]){}
You will lose the size information according to "array parameter deprecation rules", mainly because pointer doesn't hold array size information. (AKA standard said so.) So you will have to pass by reference and not by pointer value.
The parenthesis before [] is required because [] will take precedence in front of &, so in order to make & take precedence it needs to be done like
T (&a)[s]
Upvotes: 4