The compiler doesn't complain when I do this ;-)
// Myfile.h
#include <iostream>
#include <vector>
namespace std
{
template<> class vector<int>
{
public:
vector ()
{
std::cout << "Happy Halloween !!!\n";
}
};
}
Is there any way to prevent this kind of undesirable specialization of a class/function template?
I just used std:: as an example. What I'm looking for is a way to prevent this from happening to any template class.
The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.
Explicit (full) specializationAllows customizing the template code for a given set of template arguments.
Templates can have more than one parameter type. Some older compilers allow one only to specialize either all or none of the template's parameters. Compilers that support partial specialization allow the programmer to specialize some parameters while leaving the others generic.
There are three primary drawbacks to the use of templates. First, many compilers historically have very poor support for templates, so the use of templates can make code somewhat less portable. Second, almost all compilers produce confusing, unhelpful error messages when errors are detected in template code.
No, the C++ language does not provide a general mechanism by which you can say "don't allow specializations of this template".
But it may not matter. For any instantiation that your code uses already, a user provided specialization will violate the one definition rule and their program may blow up in a fireball.
If you aren't using the instantiation in your library then what they do doesn't matter.
This is one of the cases where in C++ you simply can't prevent your user from shooting themself in the foot and if they choose to do so the responsibility is on them.
What you do is specialize a standard library type inside a standard namespace.
Except for a few documented customization points (std::swap, std::hash<>) or specificly constrained specializations for User Defined Types (e.g. MySmartPtr<T>
) this is against the specification and the result is undefined behaviour.
Edit: There is no mandatory diagnostic for this kind of rule violation.
To make it marginally harder for clients of your library to mess things up, you can do this trick:
namespace Public {
namespace Hidden { // DON'T TOUCH THESE!
template <typename> struct MyType { };
}
using Hidden::MyType;
}
Now, attempting to specialize MyType<>
in namespace Hidden
will fail.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With