# Extending the namespace `std`

From cppreference.com
< cpp‎ | language

### Adding declarations to `std`

It is undefined behavior to add declarations or definitions to `namespace std` or to any namespace nested within `std`, with a few exceptions noted below

    #include <utility>
    namespace std {
        // a function definition added to namespace std: undefined behavior
        pair<int, int> operator+(pair<int, int> a, pair<int, int> b) {
            return {a.first+b.first, a.second+b.second};
        }
    }

### Adding template specializations

It is allowed to add template specializations for any standard library class (since C++20)template to the namespace `std` only if the declaration depends on at least one program-defined type and the specialization satisfies all requirements for the original template, except where such specializations are prohibited.

    // Get the declaration of the primary std::hash template.
    // We are not permitted to declare it ourselves.
    // <typeindex> is guaranteed to provide such a declaration,
    // and is much cheaper to include than <functional>.

    #include <typeindex>

    // Specialize std::hash so that MyType can be used as a key in
    // std::unordered_set and std::unordered_map
    namespace std {
        template <> struct hash<MyType> {
          std::size_t operator()(const MyType& t) const { return t.hash(); }
        };
    }

- It is undefined behavior to declare a full specialization of any member function of a standard library class template

| This section is incomplete Reason: mini-example

- It is undefined behavior to declare a full specialization of any member function template of a standard library class or class template

| This section is incomplete Reason: mini-example

- It is undefined behavior to declare a full or partial specialization of any member class template of a standard library class or class template.

| This section is incomplete Reason: mini-example

- It is undefined behavior to declare a full or partial specialization of any standard library variable template.

| This section is incomplete Reason: mini-example

- None of the templates defined in `<type_traits>` may be specialized for a program-defined type, except for std::common_type. This includes the type traits and the class template std::integral_constant.

- Specializing the template std::complex for any type other than float, double, and long double is unspecified.

- Specializations of std::hash for program-defined types must satisfy Hash requirements.

- Specializations of std::atomic must have a deleted copy constructor, a deleted copy assignment operator, and a constexpr value constructor.

- Specializations of std::shared_ptr and std::weak_ptr must be CopyConstructible and CopyAssignable. In addition, specializations of std::shared_ptr must be LessThanComparable, and convertible to bool.

- Specializations of std::istreambuf_iterator must have a trivial copy constructor, a constexpr default constructor, and a trivial destructor.

- Specializations of std::numeric_limits must define all members declared `static constexpr` in the primary template, in such a way that they are usable as integral constant expressions.

std::unary_function and std::binary_function may not be specialized. | (until C++17)

### Explicit instantiation of templates

It is allowed to explicitly instantiate a class (since C++20)template defined in the standard library only if the declaration depends on the name of at least one program-defined type and the instantiation meets the standard library requirements for the original template.

| This section is incomplete Reason: mini-example

### Other restrictions

The namespace `std` may not be declared as an `inline` namespace.

#### Addressable functions

The behavior of a C++ program is unspecified (possibly ill-formed) if it explicitly or implicitly attempts to form a pointer, reference (for free functions and static member functions) or pointer-to-member (for non-static member functions) to the a standard library function or an instantiation of a standard library function template, unless it is designated an addressable function. The only addressable functions in the standard library are I/O manipulators that are functions (or instantiations of function templates) taking a reference to a stream as their only argument, e.g. std::endl, std::boolalpha. Following code was well-defined in C++17, but leads to unspecified behaviors and possibly fails to compile since C++20:
    #include <cmath>
    #include <memory>
    int main()
    {
        auto fptr0 = &std::betaf; // by unary operator&
        auto fptr1 = std::addressof(std::betal) // by std::addressof
        auto fptr2 = std::riemann_zetaf; // by function-to-pointer implicit conversion
        auto &fref = std::riemann_zetal; // forming a reference
        auto mfptr = &std::allocator<int>::allocate; // forming a pointer to member function
    }
| (since C++20)

Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/extending_std&oldid=109617"