I was wondering if it is discouraged to overload an STL function, and if so, why?
I ran across an issue yesterday, where I found that std::fpclassify
doesn't have an integral overload on microsoft compilers (https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fpclassify?view=msvc-170) as it does for other compilers (see (4) in https://en.cppreference.com/w/cpp/numeric/math/fpclassify).
I ran across this issue when I tried to compile
T var; // T can be an integral type
std::isnan(var); //
using microsoft C compiler.
I already have a working solution to solve this issue that didn't involve overloading std::fpclassify
, but I did consider maybe just writing an overload for std::fpclassify
myself, but it seems it would have gotten hairy because the code might be compiled using non-microsoft compilers, in which case, we would already have the integral overload defined.
CodePudding user response:
Is it discouraged to overload STL functions?
You aren't allowed to add any overloads into the std
namespace. It's fine to add overloads into custom namespaces.
and if so, why?
Because the standard says so. Probably so that your program won't break when the standard (implementation) changes.
CodePudding user response:
No. There is no issue as long as you are not trying to place your custom overload inside the namespace std
, because that is undefined except in some cases.
Consider std::swap
where you are even encouraged to provide an overload when swapping two objects should do something that std::swap
cannot do:
#include <iostream>
#include <algorithm>
namespace X {
struct foo {
int value;
bool operator<(const foo& other) { return value < other.value; }
};
void swap(foo& a, foo& b) noexcept {
std::cout << "swap\n";
std::swap(a.value,b.value);
}
}
int main() {
std::vector<X::foo> v{{2},{1}};
std::iter_swap(v.begin(),v.begin() 1); // calls X::swap
std::cout << v[0].value << " " << v[1].value << "\n";
std::vector<int> w{2,1};
std::iter_swap(w.begin(),w.begin() 1); // calls std::swap
std::cout << w[0] << " " << w[1];
}
swap
1 2
1 2
This relies on ADL, which means it wont work for fundamental types or types from std
. Only if you wrap them inside a custom class inside some namespace like above you can use it for int
and the like.