I am specializing the 'less' (predicate) for a data type.
The code looks like this:
template<> struct std::less<DateTimeKey> { bool operator()(const DateTimeKey& k1, const DateTimeKey& k2) const { // Some code ... } };
When compiling (g++ 4.4.1 on Ubuntu 9.10), I get the error:
Specialization of 'template struct std::less' in different namespace
I did some research and found that there was a 'workaround' which involved wrapping the specialization in a std namespace - i.e. changing the code to:
namespace std { template<> struct less<DateTimeKey> { bool operator()(const DateTimeKey& k1, const DateTimeKey& k2) const { // Some code ... } }; }
which indeed, shuts the compiler up. However, that solution was from a post 5 years old (By the 'great' Victor Bazarof no less [pun unintended]). Is this fix still the way to go, or is there a better way of resolving this, or is the "old way" still valid?
If you need to specialize a standard algorithm, you can do so in the std namespace. It is the only thing that you are allowed to do inside that namespace according to the standard.
[lib.reserved.names]/1
It is undefined for a C++ program to add declarations or definitions to namespace std or namespaces within namespace std unless otherwise specified. A program may add template specializations for any standard library template to namespace std. Such a specialization (complete or partial) of a standard library template results in undefined behavior unless the declaration depends on a user-defined name of external linkage and unless the specialization meets the standard library requirements for the original template
Now, the question is whether you actually want to specialize std::less
. Note that std::less
will call the comparison operator defined for your type, so you can provide that operation instead of specializing the template.
The problem with specializing std::less
for your particular type is that it will cause confusion if you provide a different operation than the one performed by operator<
for your type. If they perform the same operation, just leave the default std::less
definition without specialization.
If you do not want to provide the comparison operator, but still want to use the type in associative containers or with algorithms that require a comparator, you can provide an external comparison functor by other name that will not confuse other readers (and yourself somewhere in the future).
This is still the way to do it. Unfortunately you cannot declare or define functions within a namespace like you would do with a class: you need to actually wrap them in a namespace block.
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