C++ 기술 보고서 1
1. 개요
C++ 기술 보고서 1(TR1)은 C++ 프로그래밍 언어의 표준 라이브러리를 확장하기 위한 기술 보고서이다. 이 보고서는 참조 래퍼, 스마트 포인터, 함수 객체, 메타프로그래밍 도구, 난수 생성, 수학 특수 함수, 튜플, 고정 크기 배열, 해시 테이블, 정규 표현식 등 다양한 기능을 추가했다. TR1은 Boost 라이브러리를 기반으로 하며, C 언어와의 호환성을 개선하기 위한 노력도 포함하고 있다. TR1의 후속으로 C++ 기술 보고서 2(TR2)가 제안되었으나, ISO 절차 변경으로 인해 TR2는 진행되지 않고, 대신 C++ 표준 또는 기술 사양서에 개별적으로 포함되었다.
2. 일반 유틸리티
TR1은 프로그래밍 편의성을 높이는 여러 유틸리티를 제공한다. TR1의 내용은 그 자체로 표준이 아니라 앞으로 비준되어야 할 추가 사항이다. 모든 컴파일러가 C++ 표준을 따르기 위해 TR1 요소를 포함해야 하는 것은 아니다. 그러나 TR1의 대부분은 Boost에서 이용할 수 있고, 몇몇 컴파일러/라이브러리에는 그 요소들이 모두 구현되었다.
TR1에 새로 포함될 요소들은 기존 라이브러리와 구별하기 위해 `std::tr1` 네임스페이스으로 정의되었다. TR1은 C++11에 나타난 라이브러리 추가 사항의 완전한 목록은 아니다. 예를 들어, C++11에는 TR1에서 사용할 수 없는 스레드 지원 라이브러리가 포함되어 있다.
TR1은 다음을 포함한다.
* 참조 래퍼: 참조를 알고리즘이나 함수에 값 대신 전달할 수 있도록 해 주는 기능.
* 스마트 포인터: 객체의 수명 관리를 자동화하는 스마트 포인터.
2.1. 참조 래퍼
참조를 알고리즘이나 함수에 값 대신 전달할 수 있도록 해 주는 기능이다. Boost.Ref 라이브러리를 기반으로 한다. 래퍼 참조는 `reference_wrapper` 템플릿 클래스의 인스턴스에서 가져온다. 래퍼 참조는 C++ 언어의 일반 참조('&')와 유사하다. 모든 객체에서 래퍼 참조를 얻으려면 `ref` 템플릿 클래스를 사용하고, 상수 참조의 경우에는 `cref`를 사용한다.
래퍼 참조는 특히 템플릿 함수에 유용하며, 인수 추론이 참조를 추론하지 못하는 경우(예: 인수를 전달하는 경우)에 사용된다.
```cpp
#include
#include
void f( int &r ) { ++r; }
template< class Funct, class Arg >
void g( Funct f, Arg t )
{
f(t);
}
int main()
{
int i = 0;
g( f, i ); // 'g< void(int &r), int >' 이 인스턴스화 됨
std::cout << i << "\n"; // 출력: 0
g( f, std::tr1::ref(i) ); // 'g< void(int &r), reference_wrapper
std::cout << i << "\n"; // 출력: 1
}
```
`std::tr1::reference_wrapper`는 함수나 알고리즘에 객체를 값으로 전달하는 대신 참조로 전달할 수 있게 해준다. `std::tr1::ref`와 `std::tr1::cref`를 사용하여 참조 래퍼를 생성할 수 있다.
2.2. 스마트 포인터
`std::tr1::shared_ptr`와 `std::tr1::weak_ptr`는 객체의 수명 관리를 자동화하는 스마트 포인터이다. 부스트 스마트 포인터 라이브러리를 기반으로 한다. `shared_ptr`는 참조 카운트를 추적하여 더 이상 참조되지 않는 객체를 자동으로 삭제하며, `weak_ptr`는 `shared_ptr`가 가리키는 객체에 대한 약한 참조를 제공하여 순환 참조 문제를 방지한다. 이들은 `<memory>` 헤더에 추가되어 보다 안전하게 메모리 관리를 수행할 수 있도록 돕는다.
3. 함수 객체
TR1은 `<functional>` 헤더 파일에 `function`, `bind`, `result_of`, `mem_fn` 네 가지 모듈을 추가하여 함수형 프로그래밍을 지원한다. 이들은 각각 함수 객체와 관련된 다양한 기능을 제공한다.
* 다형성 함수 래퍼 (`function`): 지정된 함수 호출 시그니처를 가진 함수 포인터, 멤버 함수 포인터, 함수 객체 등을 저장하며, Boost.Function을 기반으로 한다.
* 함수 객체 바인더 (`bind`): 매개변수를 함수 객체에 바인딩하고 함수 조합을 허용하며, Boost Bind 라이브러리를 기반으로 한다.
* 함수 반환 타입 (`result_of`): 호출 표현식의 타입을 결정한다.
* 멤버 함수 (`mem_fn`): 멤버 포인터를 함수에 대한 포인터처럼 함수 객체로 처리하도록 허용하며, Boost Mem Fn 라이브러리를 기반으로 한다.
3.1. 다형성 함수 래퍼
`std::tr1::function`은 함수 포인터, 멤버 함수 포인터, 함수 객체 등 다양한 호출 가능 객체를 저장하고 호출할 수 있는 다형성 함수 래퍼이다. Boost.Function 라이브러리를 기반으로 한다.
3.2. 함수 객체 바인더
`std::tr1::bind`는 함수 객체의 인수를 특정 값이나 다른 함수 객체에 바인딩하여 새로운 함수 객체를 생성할 수 있게 해준다. 이는 표준 `std::bind1st`와 `std::bind2nd`를 일반화한 것으로, Boost Bind 라이브러리를 기반으로 한다.
3.4. 멤버 함수
`std::tr1::mem_fn`은 멤버 함수 포인터를 함수 객체처럼 사용할 수 있게 해주는 기능이다. 이는 표준 `std::mem_fun`과 `std::mem_fun_ref`를 개선한 것으로, Boost Mem Fn 라이브러리를 기반으로 한다.
4. 메타프로그래밍 및 타입 특성
TR1은 `<type_traits>` 헤더 파일을 통해 컴파일 타임에 자료형 정보를 질의하고 조작할 수 있는 다양한 메타프로그래밍 도구들을 제공한다. 이는 Boost Type Traits 라이브러리를 기반으로 한다. `std::tr1::is_pod`, `std::tr1::has_virtual_destructor` (C++11에서는 `is_virtual_destructible`로 변경), `std::tr1::remove_extent` 등이 제공된다. 이러한 기능들은 데이터 형식에 대한 쿼리를 쉽게 하여 메타 프로그래밍을 지원한다.
최근 드래프트인 n3225에서는 `<type_traits>`에서 정의되는 `has_*`가 `is_*`로 변경되었다.
5. 수치 계산
TR1은 `
TR1에 정의된 23개의 특수 함수는 다음과 같다.함수 이름 함수 원형 수학적 표현 연관 라게르 다항식 double assoc_laguerre( unsigned n, unsigned m, double x ) ; 연관 르장드르 다항식 double assoc_legendre( unsigned l, unsigned m, double x ) ; 베타 함수 double beta( double x, double y ) ; 제1종 완전 타원 적분 double comp_ellint_1( double k ) ; 제2종 완전 타원 적분 double comp_ellint_2( double k ) ; 제3종 완전 타원 적분 double comp_ellint_3( double k, double nu ) ; 합류형 초기하 함수 double conf_hyperg( double a, double c, double x ) ; 수정 원통형 베셀 함수 double cyl_bessel_i( double nu, double x ) ; 제1종 원통형 베셀 함수 double cyl_bessel_j( double nu, double x ) ; 불규칙 수정 원통형 베셀 함수 double cyl_bessel_k( double nu, double x ) ; 원통형 노이만 함수 double cyl_neumann( double nu, double x ) ; 제1종 불완전 타원 적분 double ellint_1( double k, double phi ) ; 제2종 불완전 타원 적분 double ellint_2( double k, double phi ) ; \displaystyle E(k,\phi)=\int_0^\phi\sqrt{1-k^2\sin^2\theta}d\theta, \text{ for } \left>k\right| \le 1 제3종 불완전 타원 적분 double ellint_3( double k, double nu, double phi ) ; 지수 적분 double expint( double x ) ; 에르미트 다항식 double hermite( unsigned n, double x ) ; 초기하 급수 double hyperg( double a, double b, double c, double x ) ; 라게르 다항식 double laguerre( unsigned n, double x ) ; 르장드르 다항식 double legendre( unsigned l, double x ) ; P_l(x) = {1 \over 2^l l!} {d^l \over dx^l } (x^2 -1)^l, \text{ for } \left>x\right| \le 1 리만 제타 함수 double riemann_zeta( double x ) ; 제1종 구면 베셀 함수 double sph_bessel( unsigned n, double x ) ; 구면 연관 르장드르 함수 double sph_legendre( unsigned l, unsigned m, double theta ) ; Y_{l}^{m}(\theta, 0) \text{ where } Y_{l}^{m}(\theta, \phi) = (-1)^{m}\left[\frac{(2l+1)}{4\pi}\frac{(l-m)!}{(l+m)!}\right]^{1 \over 2} P_{l}^{m}(\cos \theta)e^{\mathrm{i}m\phi}, \text{ for }>m| \leq l 구면 노이만 함수 double sph_neumann( unsigned n, double x ) ;
각 함수는 `float`형과 `long double`형에 대해 작동하는 함수를 제공하기 위해 함수 이름에 f 또는 l 접미사를 추가하여 사용할 수 있다.
5.1. 의사 난수 생성
TR1은 `
5.2. 수학 특수 함수
TR1은 `
TR1에 정의된 23개의 특수 함수는 다음과 같다.함수 이름 함수 원형 수학적 표현 연관 라게르 다항식 double assoc_laguerre( unsigned n, unsigned m, double x ) ; 연관 르장드르 다항식 double assoc_legendre( unsigned l, unsigned m, double x ) ; 베타 함수 double beta( double x, double y ) ; 제1종 완전 타원 적분 double comp_ellint_1( double k ) ; 제2종 완전 타원 적분 double comp_ellint_2( double k ) ; 제3종 완전 타원 적분 double comp_ellint_3( double k, double nu ) ; 합류형 초기하 함수 double conf_hyperg( double a, double c, double x ) ; 수정 원통형 베셀 함수 double cyl_bessel_i( double nu, double x ) ; 제1종 원통형 베셀 함수 double cyl_bessel_j( double nu, double x ) ; 불규칙 수정 원통형 베셀 함수 double cyl_bessel_k( double nu, double x ) ; 원통형 노이만 함수 double cyl_neumann( double nu, double x ) ; 제1종 불완전 타원 적분 double ellint_1( double k, double phi ) ; 제2종 불완전 타원 적분 double ellint_2( double k, double phi ) ; \displaystyle E(k,\phi)=\int_0^\phi\sqrt{1-k^2\sin^2\theta}d\theta, \text{ for } \left>k\right| \le 1 제3종 불완전 타원 적분 double ellint_3( double k, double nu, double phi ) ; 지수 적분 double expint( double x ) ; 에르미트 다항식 double hermite( unsigned n, double x ) ; 초기하 급수 double hyperg( double a, double b, double c, double x ) ; 라게르 다항식 double laguerre( unsigned n, double x ) ; 르장드르 다항식 double legendre( unsigned l, double x ) ; P_l(x) = {1 \over 2^l l!} {d^l \over dx^l } (x^2 -1)^l, \text{ for } \left>x\right| \le 1 리만 제타 함수 double riemann_zeta( double x ) ; 제1종 구면 베셀 함수 double sph_bessel( unsigned n, double x ) ; 구면 연관 르장드르 함수 double sph_legendre( unsigned l, unsigned m, double theta ) ; Y_{l}^{m}(\theta, 0) \text{ where } Y_{l}^{m}(\theta, \phi) = (-1)^{m}\left[\frac{(2l+1)}{4\pi}\frac{(l-m)!}{(l+m)!}\right]^{1 \over 2} P_{l}^{m}(\cos \theta)e^{\mathrm{i}m\phi}, \text{ for }>m| \leq l 구면 노이만 함수 double sph_neumann( unsigned n, double x ) ;
각 함수는 `float`형과 `long double`형에 대해 작동하는 함수를 제공하기 위해 함수 이름에 f 또는 l 접미사를 추가하여 사용할 수 있다.
6. 컨테이너
TR1은 여러 컨테이너를 제공한다.
* 튜플: `
* 고정 크기 배열: `
* 해시 테이블: `
6.1. 튜플
TR1은 `
6.2. 고정 크기 배열
TR1은 `
6.3. 해시 테이블
TR1은 `
모든 해시 테이블과 마찬가지로, 일반적으로 요소의 상수 시간 조회를 제공하지만, 최악의 경우 컨테이너 크기에 비례하여 선형 시간이 걸릴 수 있다.
`unordered_set`, `unordered_map`이 `hash_set` (SGI 버전 STL에 포함된 라이브러리) 등의 이름이 아닌 이유는, 표준 `set`, `map`은 이터레이터를 사용하여 정렬된 요소를 접근할 수 있는 반면, `unordered_set`, `unordered_map`은 불가능하다는 것을 나타내기 위함이다. 즉, 구현이 아닌 인터페이스(사용법)에서 이름을 따온 것이다.
7. 정규 표현식
TR1은 `
8. C 호환 라이브러리
C++(C++)는 C 언어와 호환되도록 설계되었지만, 표준이 달라 C의 엄격한 상위 집합은 아니다. TR1은 <complex>, <locale>, <cmath> 등 C++ 라이브러리의 다양한 헤더에 추가 기능을 제공하여 이러한 차이점을 해결하려고 시도한다. 이러한 변경 사항은 C++를 C99 버전의 C 표준에 더 가깝게 만들지만, C99의 모든 부분이 TR1에 포함된 것은 아니다.
9. C++ Technical Report 2 (TR2)
TR1 이후에 제안된 C++ 표준 라이브러리 확장이었으나, 정식으로 출판되지는 않았다. 2005년에 TR2에 대한 제안 요청이 있었으며, 유니코드, XML/HTML, 네트워킹, 그리고 초보 프로그래머의 사용 편의성에 특별한 관심이 쏟아졌다.
TR2에서 제안된 일부 기능은 다음과 같다.
* 스레드
* Asio C++ 라이브러리 (네트워킹)
* 시그널/슬롯
* 파일 시스템 라이브러리 - Boost 파일 시스템 라이브러리를 기반으로 경로, 파일 및 디렉터리를 쿼리/조작
* Boost Any 라이브러리
* 어휘 변환 라이브러리
* 새로운 문자열 알고리즘
* TR2의 숫자 라이브러리에 대한 대수적 속성의 보다 완전한 분류
* TR2를 위한 연관 컨테이너에 이종 비교 조회
TR2 제안 요청이 발행된 후, ISO 절차가 변경되어 TR2는 더 이상 진행되지 않게 되었다. 대신 C++에 대한 개선 사항은 여러 기술 사양서에 게시될 예정이다. 위에 나열된 일부 제안은 이미 C++ 표준 또는 기술 사양서의 초안 버전에 포함되어 있다.