Circumventing template specialization
Suppose I am a user of a Certain Template Library (CTL
) which defines a templat开发者_如何转开发e, named, say, Hector
template <class T>
class Hector {...};
And in its documentation it gives many guarantees about Hector
template behavior.
But then it also defines a specialization for a certain type Cool
template <>
class Hector<Cool> {....};
The purpose of the specialization is a more optimized implementation of Hector
, but unfortunately because of this optimization many guarantees of Hector
are violated.
Currently I really don't need the optimization, I'd rather preserve all the guarantees of Hector
. Is there any way I could, without changing the library code (CTL
is a highly respectable library, you know), circumvent the specialization? Any way at all? Maybe write some sort of wrapper? Anything? I just want to the compiler to generate code for Hector<Cool>
in a normal, non-optimized way, with all the guarantees.
Are you able to use the related template Reque
that doesn't have the undesired specialization? Otherwise I think you'd need to create a wrapper for Cool
so that the specialization isn't used.
You could wrap cool in a dummy type to prevent the template from specializing it.
No. And even if it can be done in some esoteric fashion, don't. Circumventing language features should set off an alarm.
You have to wrap the value or use a different type like char
instead of bool
(they behave similarly), giving std::vector<char>
instead of std::vector<bool>
.
Here's a little generic disguiser:
template <typename T>
struct Drool
{
Drool(T d) : b(d) { }
inline operator T() const { return b; }
inline Drool<T> & operator=(T d) { b = d; return *this; }
private:
T b;
};
Now you can say Hector<Drool<Cool>>
.
Improved version according to Xeo:
template <typename T>
struct Drool
{
Drool(const T & d) : b(d) { }
Drool(Drool && o) = default;
inline operator const T & () const { return b; }
inline operator T & () { return b; }
private:
T b;
};
- Open the
standardcertain implementation - Ctrl+A
- Ctrl+C
- Create a new file called
"my_hector.h"
- Ctrl+V
- Remove the specialisation
- Search and replace
#include <hector>
with#include "my_hector.h"
[ Edit for @Xeo ;-) ] - Rename identifiers that begin with two leading underscores followed by a lowercase letter, and all identifiers that begin with a single leading underscore following by an uppercase letter.
精彩评论