Templates for fixed sized containers is a valid practice. It fills some niche needs: the standard library offers for example std::array
as a more consistent alternative to native fixed sized arrays. But it's not very flexible, as the more frequent use of std::vector
over std::array
may suggest.
The main issue is that each instantiation, e.g. String<10>
or String<11>
, is a different type, unrelated to its cousins. So your operator=
could not assign a String<10>
to a String<11>
. And if you'd pass it as parameter to a function, the function itself should be a template function. So better keep this kind of templates for the cases where it's really critical to have fixed size containers.
There are other drawbacks that are less constraining. But you should be aware of :
- A count of the number of active items may probably be needed (e.g. considering your
Append()
). A much more flexible variable-length container could then be obtained with a very little overhead.
- If on contrary the container is systematically filled, all its items will get constructed when constructing the container: depending on the complexity of the default item, it might be a potential performance issue for containers of a very large size.
- Compilers are not required to generate common code for
String<10>
and String<11>
. You might therefore end with multiple copies of very similar binary code and a bloated executable.
Not related: your copy assignment overload should use the String& operator=(const String& rhs);
signature: this would allow rhs
to be a temporary or a constant String
. More about recommended overloads here.
String<10> ten; String<12> twelve; twelve.Append(ten);
?length
is used in some sensible way? Nonsensical examples will attract downvotes and close votes.std::array
? - en.cppreference.com/w/cpp/container/array