h8n2
h8n2

Reputation: 679

Is it discouraged to overload STL functions?

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://learn.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.

Upvotes: 0

Views: 87

Answers (2)

eerorika
eerorika

Reputation: 238351

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.

Upvotes: 2

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122458

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];
}

Output:

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.

Upvotes: 0

Related Questions