I completely disagree with the blog.
The
#pragma once
directive
is a very wonderful thing, when the compiler toolchain supports it, but it is the
pragma directive that is fragile, not the include guards.
The problem lies with the filesystem. It is entirely possible to provide the same physical file to the preprocessor in such a way as to be impossible or impractical to recognize as the same exact file. Likewise, it is possible to have two files, in two separate locations, which are actually copies of each other -- either byte by byte or in some way reformatted. (This can and does happen! Sometimes it takes years before someone notices and fixes the error in CVS/SVN/repository.) The pragma once directive is powerless to defeat such inputs.
The include guards will
always work when appropriately named. If you are concerned with name collisions, especially because you named your file something like "strings.h" or some like high-collision value, naming your include macro "STRINGS_H" is not just foolhardy, but positively asking for trouble.
Use a solid convention for unique names. A good one is, for example, just a date-time stamp along with the filename. I always add the library name as well. The odds for collision here are infinitesimal.
1 2
|
#ifndef SPIFF_STRINGS_20110115_2219Z_HPP
#define SPIFF_STRINGS_20110115_2219Z_HPP
|
Many compilers are also optimized to recognize include guards and have the same effect as using pragma once. GCC is one such toolchain.
A good practice is to use both pragma once and include guards. Those compilers which optimize on pragma once/include guard filename recognition will work nicely. When they fail, or if the compiler doesn't optimize on filename recognition, then the include guard will catch it.
─────────────────────────
For core, integral/numeric types you don't need a reference, as just making a copy is just as fast/secure/efficient/etc. Hence, there is no need to say
const float& x
over
float x
. Where copying is prohibitive (that is, expensive), like
std::string s
would be, or if you don't know the type, as in templated classes, then you want to use a const reference
const std::string& s
.
─────────────────────────
@
barliesque
I'm not sure, but it is probably because your copy constructor assumes a different templated type?
Hope this helps.