Originally Posted by
Elysia
It is not as if this takes 100x longer to implement. It takes very little time and prevents against mistakes, so what is the harm?
When I answer this, I hope you link to it, or something, so that other people can read it when you talk about it again. Also if you put it in your signature, I imagine it will be hard for you to forget about the huge downsides in the future.
It causes code bloat. After fixing warnings, it compiles and comes up with an executable that is ~920 KB in size. Let's exacerbate the problem!
Code:
#include <string>
#include <iostream>
#include <algorithm>
#define SIZE(x) sizeof(x) / sizeof(x[0])
template <typename T, size_t N>
void foo(T (&arr)[N])
{
int bar[N];
std::copy(arr, arr + N, bar);
for (size_t i = 0; i < N; i++)
std::cout << "bar[" << i << "]: " << bar[i] << std::endl;
}
int main()
{
int _foo[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int _bar[20] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
double _quz[4] = {1.1412, 3.1415, 1.618, 1.01234567801};
for (size_t i = 0; i < SIZE(_foo); i++)
std::cout << "_foo[" << i << "]: " << _foo[i] << std::endl;
foo(_foo);
for (size_t i = 0; i < SIZE(_bar); i++)
std::cout << "_bar[" << i << "]: " << _bar[i] << std::endl;
foo(_bar);
for (size_t i = 0; i < SIZE(_quz); i++)
std::cout << "_bar[" << i << "]: " << _quz[i] << std::endl;
foo(_quz);
return 0;
}
925 KB
Code:
#include <string>
#include <iostream>
#include <algorithm>
#define SIZE(x) sizeof(x) / sizeof(x[0])
template <typename T, size_t N>
void foo(T (&arr)[N])
{
int bar[N];
std::copy(arr, arr + N, bar);
for (size_t i = 0; i < N; i++)
std::cout << "bar[" << i << "]: " << bar[i] << std::endl;
}
int main()
{
int _foo[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int _bar[20] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
double _quz[4] = {1.1412, 3.1415, 1.618, 1.01234567801};
float _quuz[4] = {1.1412, 3.1415, 1.618};
for (size_t i = 0; i < SIZE(_foo); i++)
std::cout << "_foo[" << i << "]: " << _foo[i] << std::endl;
foo(_foo);
for (size_t i = 0; i < SIZE(_bar); i++)
std::cout << "_bar[" << i << "]: " << _bar[i] << std::endl;
foo(_bar);
for (size_t i = 0; i < SIZE(_quz); i++)
std::cout << "_bar[" << i << "]: " << _quz[i] << std::endl;
foo(_quz);
for (size_t i = 0; i < SIZE(_quz); i++)
std::cout << "_bar[" << i << "]: " << _quz[i] << std::endl;
foo(_quuz);
return 0;
}
929 KB
Now, I'm not sure, but eventually you can call this ridiculous. What sort of design has to get bigger for each wrinkle in the code? Every array type, and size means that you have to make a whole new function JUST to accommodate the reference type. The only way I changed the code in your original post was to reap the benefits of templates in making that less arduous. I think this ruins the usefulness of the idea though. Every other method of deducing N is less expensive in terms of space.
You can use this technique at least a little smarter than what you're actually teaching people to do. If generating the size is really a concern, use this code to do that and nothing else -- follow convention for passing in sequences. Use two iterators or one iterator and a size parameter. Designing a whole program as lazily as this example is going to mean a huge exe in the end.
The bad thing is that you will always pay the file size penalty. Maybe you just don't care but it's nothing to sneeze at. Mind you, the whole code bloat thing applies to templates just as much, but this is a particularly dumb use of code in the name of security. I wish I could wave the security wand and make all my poorly thought out designs OK.