Namespaces
Variants

Extending the namespace std

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

목차

std 에 선언 추가하기

std 네임스페이스나 std 내부에 중첩된 어떤 네임스페이스에도 선언이나 정의를 추가하는 것은 미정의 동작입니다. 아래에 명시된 몇 가지 예외를 제외하고.

#include <utility>
namespace std
{
    // std 네임스페이스에 추가된 함수 정의: 정의되지 않은 동작
    pair<int, int> operator+(pair<int, int> a, pair<int, int> b)
    {
        return {a.first + b.first, a.second + b.second};
    }
}

템플릿 특수화 추가하기

클래스 템플릿

표준 라이브러리 클래스 템플릿에 대한 템플릿 특수화를 std 네임스페이스에 추가하는 것이 허용됩니다. 단, 선언이 적어도 하나의 프로그램 정의 타입 에 의존하고, 해당 특수화가 원본 템플릿의 모든 요구사항을 만족하는 경우에 한합니다. 단, 이러한 특수화가 명시적으로 금지된 경우는 예외입니다.

// 기본 std::hash 템플릿의 선언을 가져옵니다.
// 우리는 이를 직접 선언할 수 없습니다.
// <typeindex>는 이러한 선언을 제공함이 보장되며,
// <functional>을 포함하는 것보다 훨씬 비용이 적게 듭니다.
#include <typeindex> 
// MyType이 std::unordered_set과 std::unordered_map에서 키로 사용될 수 있도록
// std::hash를 특수화합니다. std 네임스페이스를 열면
// 의도치 않게 정의되지 않은 동작을 초래할 수 있으며,
// 클래스 템플릿을 특수화하는 데 필요하지 않습니다.
template<>
struct std::hash<MyType>
{
    std::size_t operator()(const MyType& t) const { return t.hash(); }
};
  • 템플릿 std::complex float , double , 그리고 long double 이외의 타입에 대해 특수화하는 것은 명시되지 않았습니다.
  • std::numeric_limits 의 특수화는 기본 템플릿에서 선언된 모든 멤버들을 static const (until C++11) static constexpr (since C++11) 로 정의해야 하며, 이러한 멤버들이 integral constant expressions 로 사용 가능하도록 해야 합니다.
  • 프로그램 정의 타입에 대한 std::hash 특수화는 Hash 요구 사항을 만족해야 합니다.
  • std::atomic 특수화는 삭제된 복사 생성자, 삭제된 복사 할당 연산자, 그리고 constexpr 값 생성자를 가져야 합니다.
  • std::istreambuf_iterator 특수화는 trivial 복사 생성자, constexpr 기본 생성자, 그리고 trivial 소멸자를 가져야 합니다.
(C++11부터)
(C++17까지)

표준 라이브러리 클래스 또는 클래스 템플릿의 멤버 클래스 템플릿에 대한 완전 특수화 또는 부분 특수화를 선언하는 것은 정의되지 않은 동작입니다.

함수 템플릿과 템플릿의 멤버 함수

std 네임스페이스에 표준 라이브러리 함수 템플릿의 특수화를 추가하는 것은 선언이 프로그램 정의 타입 에 최소 하나 이상 의존하고, 해당 특수화가 원본 템플릿의 모든 요구사항을 만족하는 경우에만 허용됩니다. 단, 이러한 특수화가 명시적으로 금지된 경우는 예외입니다.

(C++20 이전)

표준 라이브러리 함수 템플릿의 완전 특수화를 선언하는 것은 정의되지 않은 동작입니다.

(C++20 이후)

표준 라이브러리 클래스 템플릿의 어떤 멤버 함수에 대한 완전 특수화를 선언하는 것은 정의되지 않은 동작입니다:

표준 라이브러리 클래스 또는 클래스 템플릿의 멤버 함수 템플릿 전체 특수화를 선언하는 것은 정의되지 않은 동작입니다:

변수 템플릿

명시적으로 허용된 경우를 제외하고, 모든 표준 라이브러리 변수 템플릿의 완전 특수화 또는 부분 특수화를 선언하는 것은 정의되지 않은 행동입니다.

(C++20부터)
(C++14부터)

템플릿의 명시적 인스턴스화

표준 라이브러리에 정의된 class (since C++20) 템플릿을 명시적으로 인스턴스화하는 것은 선언이 최소한 하나의 program-defined type 이름에 의존하고, 해당 인스턴스화가 원본 템플릿에 대한 표준 라이브러리 요구 사항을 충족하는 경우에만 허용됩니다.

기타 제한 사항

네임스페이스 std 인라인 네임스페이스 로 선언될 수 없습니다.

주소 지정 제한

C++ 프로그램이 표준 라이브러리 함수나 표준 라이브러리 함수 템플릿의 인스턴스에 대한 포인터, 참조(자유 함수와 정적 멤버 함수의 경우) 또는 멤버 포인터(비정적 멤버 함수의 경우)를 명시적 또는 암시적으로 생성하려 시도할 경우, 그 동작은 명시되지 않으며(잘못된 형식일 수도 있음) 주소 지정 가능 함수 (아래 참조)로 지정된 경우를 제외하고는 허용되지 않습니다.

다음 코드는 C++17에서는 올바르게 정의되었지만, C++20부터는 명시되지 않은 동작을 초래하며 컴파일되지 않을 수 있습니다:

#include <cmath>
#include <memory>
int main()
{
    // 단항 연산자 & 사용
    auto fptr0 = &static_cast<float(&)(float, float)>(std::betaf);
    // std::addressof 사용
    auto fptr1 = std::addressof(static_cast<float(&)(float, float)>(std::betaf));
    // 함수-포인터 암시적 변환 사용
    auto fptr2 = static_cast<float(&)(float)>(std::riemann_zetaf);
    // 참조 생성
    auto& fref = static_cast<float(&)(float)>(std::riemann_zetaf);
}

지정된 주소 지정 가능 함수

(C++20부터)

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
LWG 120 C++98 사용자가 비사용자 정의 타입에 대해 표준 라이브러리
템플릿을 명시적으로 인스턴스화할 수 있었음
금지됨
LWG 232 C++98 선언이 외부 링크를 가진 사용자 정의 이름에 의존하는 경우
(비사용자 정의 타입을 참조할 수 있음)
사용자가 표준 라이브러리 템플릿을 명시적으로 특수화할 수 있었음
사용자 정의 타입에 대해서만
허용됨
LWG 422 C++98 사용자가 전체 표준 라이브러리 클래스나 클래스 템플릿을
특수화하지 않고도 개별 멤버나 멤버 템플릿을 특수화할 수 있었음
이 경우 동작은
정의되지 않음