48 |
49 | 이 외에도 stable, mutable_, stability_counter_type, arity, store_parent_pointer 라는 설정이 있다.
50 |
51 |
--------------------------------------------------------------------------------
/boost_container/index.md:
--------------------------------------------------------------------------------
1 | # boost.container
2 | 1.48 버전에서 새로 추가.
3 | STL 호환 컨테이너 라이브러리
4 | C++03 컴파일러에서 C++11의 기능을 사용할 수 있음
5 | - Move semantics
6 | - placement insertion
7 | - recursive containers.
8 |
9 | 
10 |
11 |
12 | - [Heap](heap.md)
13 | - [static_vector](static_vector.md)
14 | - [stable_vector](stable_vector.md)
15 | - [flat_(multi)map/set](flat_map-set.md)
16 | - [독자적인 allocator 사용하기](allocator.md)
17 |
18 |
19 | ## tool
20 | - [CPPDebuggerVisualizers](https://github.com/KindDragon/CPPDebuggerVisualizers)
21 |
22 |
23 |
24 | ## 참고
25 | - [Intrusive data structure 소개](http://www.slideshare.net/ohyecloudy/intrusive-data-structure)
--------------------------------------------------------------------------------
/boost_container/resource/001.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacking75/edu_cpp_Boost_Lib/3e5741e5cbd1773fa4ad8479e74f37ee642d74c5/boost_container/resource/001.PNG
--------------------------------------------------------------------------------
/boost_container/resource/002.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacking75/edu_cpp_Boost_Lib/3e5741e5cbd1773fa4ad8479e74f37ee642d74c5/boost_container/resource/002.PNG
--------------------------------------------------------------------------------
/boost_container/resource/003.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacking75/edu_cpp_Boost_Lib/3e5741e5cbd1773fa4ad8479e74f37ee642d74c5/boost_container/resource/003.PNG
--------------------------------------------------------------------------------
/boost_container/resource/004.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacking75/edu_cpp_Boost_Lib/3e5741e5cbd1773fa4ad8479e74f37ee642d74c5/boost_container/resource/004.PNG
--------------------------------------------------------------------------------
/boost_container/resource/005.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacking75/edu_cpp_Boost_Lib/3e5741e5cbd1773fa4ad8479e74f37ee642d74c5/boost_container/resource/005.PNG
--------------------------------------------------------------------------------
/boost_container/resource/006.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacking75/edu_cpp_Boost_Lib/3e5741e5cbd1773fa4ad8479e74f37ee642d74c5/boost_container/resource/006.PNG
--------------------------------------------------------------------------------
/boost_container/resource/007.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacking75/edu_cpp_Boost_Lib/3e5741e5cbd1773fa4ad8479e74f37ee642d74c5/boost_container/resource/007.PNG
--------------------------------------------------------------------------------
/boost_container/resource/008.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacking75/edu_cpp_Boost_Lib/3e5741e5cbd1773fa4ad8479e74f37ee642d74c5/boost_container/resource/008.PNG
--------------------------------------------------------------------------------
/boost_container/resource/009.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacking75/edu_cpp_Boost_Lib/3e5741e5cbd1773fa4ad8479e74f37ee642d74c5/boost_container/resource/009.PNG
--------------------------------------------------------------------------------
/boost_container/resource/010.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacking75/edu_cpp_Boost_Lib/3e5741e5cbd1773fa4ad8479e74f37ee642d74c5/boost_container/resource/010.PNG
--------------------------------------------------------------------------------
/boost_container/resource/011.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacking75/edu_cpp_Boost_Lib/3e5741e5cbd1773fa4ad8479e74f37ee642d74c5/boost_container/resource/011.PNG
--------------------------------------------------------------------------------
/boost_container/resource/012.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacking75/edu_cpp_Boost_Lib/3e5741e5cbd1773fa4ad8479e74f37ee642d74c5/boost_container/resource/012.PNG
--------------------------------------------------------------------------------
/boost_container/resource/013.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacking75/edu_cpp_Boost_Lib/3e5741e5cbd1773fa4ad8479e74f37ee642d74c5/boost_container/resource/013.PNG
--------------------------------------------------------------------------------
/boost_container/resource/014.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacking75/edu_cpp_Boost_Lib/3e5741e5cbd1773fa4ad8479e74f37ee642d74c5/boost_container/resource/014.PNG
--------------------------------------------------------------------------------
/boost_container/stable_vector.md:
--------------------------------------------------------------------------------
1 | ## stable_vector
2 | - 이름 그대로 안정된 vector.
3 | - std::vector는 저장된 요소의 연속성을 보장하지만 반복자가 무효화 될 수 있다.(이 문제를 해결하려면 std::list 사용)
4 | - stable_vector는 요소의 연속성 확보 보다 요소를 가리키는 포인터를 연속으로 보존.
5 | - 리스트와 비슷하지만 임의접근이 가능하다.
6 | - 삽입, 삭제가 발생하여도 저장된 요소가 이동하지 않는다.
7 | - 요소 중에 새로운 요소를 추가하여도 그 이후의 모든 요소를 이동하지 않고 포인터를 복사하는 것으로 완료.
8 |
9 |
10 | ### 예제 코드
11 | ```C++
12 | std::vector v;
13 |
14 | v.push_back(1);
15 | auto const it = v.begin();
16 |
17 | for (int i = 2; i < 10; ++i)
18 | v.push_back(i);
19 |
20 | // ???
21 | std::cout << *it;
22 | ```
23 |
24 | ```C++
25 | // http://codezine.jp/article/detail/8259
26 |
27 | void memory_usage() {
28 | cout << "\n=== memory_usage\n";
29 | {
30 | std::vector v;
31 | for ( int i = 0; i < 5; ++i ) {
32 | v.emplace_back(i);
33 | }
34 | cout << "\n--- std::vector : before\n";
35 | for ( const int& val : v ) {
36 | cout << setw(4) << val << " @ " << static_cast(&val) << endl;
37 | }
38 |
39 | cout << "\n--- std::vector : after\n";
40 | v.erase(begin(v)+2);
41 | for ( const int& val : v ) {
42 | cout << setw(4) << val << " @ " << static_cast(&val) << endl;
43 | }
44 |
45 | cout << endl;
46 | }
47 |
48 | ```
49 | 
50 | 메모리가 연속적으로 할당 되지 않는다.
51 |
52 | ```C++
53 | //http://codezine.jp/article/detail/8259
54 |
55 | void memory_detail() {
56 | cout << "\n=== boost::container::stable_vector\n--- 3 insertions\n";
57 | boost::container::stable_vector> vv;
58 | for ( int i = 0; i < 3; ++i ) {
59 | vv.emplace_back(i);
60 | }
61 | for ( int item : vv) {
62 | cout << item << ' ';
63 | }
64 | cout << endl;
65 | }
66 | ```
67 | 
68 |
69 | 포인터 배열의 각 요소에 node가 매달려서, 각 노드는 반대 방향 포인터를 가지고 있다.
70 | 그래서 stable_vecto의 반복자는 각 node를 가리킨다. 그래서 어떤 반복자에 대해서,
71 | node에서 node*열에 오르고
72 | 거기서 n개 이동한다(포인터에 n을 더한다)
73 | node에 내린다
74 | 라는 조작으로 n개 옆으로 이동할 수 있다.
75 | 이런 편법으로 랜덤 접근을 구현하고 있어서 예를 들면 std::sort()로 정렬할 수 있다.
76 | 또 이 구조에 의해 어떤 요소를 가리키는 반복자는(그 요소를 삭제하지 않는 한) 요소의 삽입/삭제에 따른 무효가 되는 일이 없다.
77 | 
78 |
79 |
80 | ### 예제 프로그램
81 | - stable_vector_01
82 | - stable_vector_02
83 |
84 |
85 | ### 장단점
86 | - 요소의 안정성을 중시해서 각종 성능에서는 vector, list에 비해 다소 떨어진다.
87 | - 요소 접근을 위해 1회 불필요한 간접 참조를 해야하므로 vector 보다 느리다.
88 | - 요소들을 연속해서 보존하고 있다는 것을 보증할 수 없으므로 캐시 효율도 나쁘다.
89 | - vector 보다 많은 메모리를 필요로 한다.
90 | (c + 1)p + (n + 1)(e + p)
91 | c=capacity(), p=sizeof(T*), n=size(), e=sizeof(T)
92 | vector는 c×e
93 | - 그러나 때로는 vector 보다 더 적은 메모리를 사용하기도 한다.
94 | c >> n 일 때는 요소를 저장하기 위한 영역이 vector은 cXe 이지만 stable_vector는 nXe만 필요로 한다.
95 | - 이름과 다르게 vector의 대체보다는 list의 대체에 더 가깝다.
96 |
97 |
98 |
--------------------------------------------------------------------------------
/boost_container/static_vector.md:
--------------------------------------------------------------------------------
1 | ## static_vector
2 | - 1.54에 추가 되었다.
3 | - std::vector와 std::array 양쪽의 특성을 모두 가진 하이브리드 컨테이너.
4 | - 정적인 영역을 사용하는 가변 길이 배열.static_vector 에서 N 이하의 가변 길이 배열이다.
5 | - 고정 capacity를 두 번째 템플릿 인수로 지정하면 그 사이즈가 정적으로 영역을 확보한다.
6 | - 정해진 capacity를 넘지 않도록 추가/삭제를 해야 한다.
7 | - 정해진 capacity를 넘지 않도록 추가/삭제를 해야 한다.범위를 넘으면 예외 발생
8 | - 임의접근 가능.
9 | - 제일 뒤 삽입/삭제는 정수 시간
10 | - 선두나 중간 삽입/삭제는 선형 시간
11 | - 최대 요소 수가 다른 static_vector과 static_vector 간에 복사를 할 수 있지만 target(좌변)의 capacity()가 source(우변) size() 보다 작으면 std:bad_alloc 예외 발생
12 | - 할당자를 가지지 않는 것만 빼고는 std::vector와 같다.
13 |
14 |
15 | ### 예제 코드
16 | ```C++
17 | // http://faithandbrave.hateblo.jp/entry/20130712/1373614497
18 |
19 | #include
20 | #include
21 |
22 | int main()
23 | {
24 | boost::container::static_vector v;
25 |
26 | // 요소 추가
27 | v.push_back(3);
28 | v.push_back(1);
29 | v.push_back(4);
30 |
31 | // 모든 요소 출력
32 | for (int x : v) {
33 | std::cout << x << std::endl;
34 | }
35 |
36 | // capacity를 넘는 요소를 추가하려고 하면 bad_alloc 예외가 던져진다
37 | // v.push_back(5);
38 | }
39 | ```
40 |
23 |
24 | 이처럼 구간의 기반이 되는 T 타입을 템플릿 인수에 구간 타입 boost::numeric::interval을 사용할 수 있다.
25 | 사실, 이 구간 타입 interval과 2 개의 템플릿 인수를 취하도록 선언 되어 있고, Policies에 다양하게 지정하여 세세한 행동을 바꿀 수 있다.
26 | 기본값은 기본 정책이 사용되고, 보통은 기본만으로 충분하다.
27 |
28 | Remark. 구간 연산 라이브러리는 어떤 계산기 · 어떤 컴파일러에 대해서도 "정확한 계산"을 지원하고 있는 것은 아니다. 사용하고 있는 컴퓨터 환경에서 구간 연산 라이브러리를 올바르게 사용할 수 있는지 여부는 공식 문서 등으로 확인 해야 한다.
29 |
30 |
31 |
32 | ## 사칙 연산과 기본 함수
33 |
34 | ### 구간끼리의 사칙 연산
35 | 부동 소수점 오차까지 고려하면서 구간의 수 모두에 대한 연산 결과를 모두 포함하도록 구간을 계산하여 반환한다.
36 |
37 | test-interval-arith-IRxIR.cpp:
38 | ```
39 | #include
40 | #include
41 | #include
42 |
43 | int main () {
44 | typedef double R;
45 | typedef boost::numeric::interval IR;
46 | using std::cout;
47 | using std::endl;
48 | const IR a(1.0, 2.0);
49 | const IR b(3.0, 4.0);
50 | cout << "a = " << a << endl;
51 | cout << "b = " << b << endl;
52 | cout << "a + b = " << a + b << endl;
53 | cout << "a - b = " << a - b << endl;
54 | cout << "a * b = " << a * b << endl;
55 | cout << "a / b = " << a / b << endl;
56 | return 0;
57 | }
58 | ```
59 |
60 | a = [1,2]
61 | b = [3,4]
62 | a + b = [4,6]
63 | a - b = [-3,-1]
64 | a * b = [3,8]
65 | a / b = [0.25,0.666667]
66 |
67 | [Wandbox](https://wandbox.org/permlink/8qtcQb4XXNOkLEzw )
68 |
69 | 또한 좌변 값에 사칙 연산을 직접 수행하는 연산자 +=, -=, *=, /= 도 있다.
70 |
71 | Remark. 일반적으로 구간의 이항 연산 +과 -는 서로 반대 연산의 관계는 되지 않는다. 예를 들어, 원래 오차가 없이 + 와 - 가 서로 반대 연산의 관계에 있는 int를 기반으로 하는 구간 타입 interval의 경우를 생각해도 [1, 2] - [1, 2]는 [0, 0]는 안된다. * 와 / 도 마찬가지이다. 따라서, 일반적으로는 구간 연산의 반복으로 구간은 점점 커져간다. 부동 소수점 타입의 경우에는 구간 타입을 생각하여 원래 역 연산 관계에 없었던 사칙 연산이 가지는 '오차'라는 성격이 더 두드러 졌다고도 할 수 있다.
72 |
73 |
74 | ### 구간 수의 사칙 연산
75 | 사칙 연산의 인수의 한쪽은 베이스 타입 T의 값으로 제공 할 수 있다. 이러한 경우 먼저 인수를 interval로 변환하여 연산을 수행한 것과 같은 결과가 된다(이것은 이후 나오는 다른 함수에 대해서도 대략 마찬가지이다).
76 | Remark. interval는 하단과 상단의 2 인자를 취하는 생성자 이외에도 베이스 타입 T의 값 x를 취하고, 일점 구간[x, x]를 만드는 1 인자 생성자가 있다.
77 |
78 | test-interval-arith-IRxR.cpp:
79 | ```
80 | #include
81 | #include
82 | #include
83 |
84 | int main () {
85 | typedef double R;
86 | typedef boost::numeric::interval IR;
87 | using std::cout;
88 | using std::endl;
89 | const IR a(1.0, 2.0);
90 | const R b = 3.0;
91 | cout << "a = " << a << endl;
92 | cout << "b = " << b << endl;
93 | cout << "a + b = " << a + b << endl;
94 | cout << "a - b = " << a - b << endl;
95 | cout << "a * b = " << a * b << endl;
96 | cout << "a / b = " << a / b << endl;
97 | return 0;
98 | }
99 | ```
100 |
101 |
102 | ### 숫자끼리의 사칙 연산
103 | 두 인수를 베이스 타입으로 주고 사칙하려면 어떻게할까? 이런 때에는 boost::numeric::interval_lib 에 정의된 함수 add, sub, mul, div을 사용한다. 이들은 베이스 타입 T 값을 2개의 인수로 잡고, 사칙 연산 절단 · 절상을 각각 하단 · 상단으로 하는 interval 타입의 구간을 계산하여 반환한다.
104 |
105 | test-interval-arith-RxR.cpp:
106 | ```
107 | #include
108 | #include
109 | #include
110 |
111 | int main () {
112 | typedef double R;
113 | typedef boost::numeric::interval IR;
114 | using std::cout;
115 | using std::endl;
116 | const R a = 1.7;
117 | const R b = 3.3;
118 | cout << "a = " << a << endl;
119 | cout << "b = " << b << endl;
120 | {
121 | using namespace boost::numeric::interval_lib;
122 | cout << "a + b = " << add(a, b) << "w(" << width(add(a, b)) << ")" << endl;
123 | cout << "a - b = " << sub(a, b) << "w(" << width(sub(a, b)) << ")" << endl;
124 | cout << "a * b = " << mul(a, b) << "w(" << width(mul(a, b)) << ")" << endl;
125 | cout << "a / b = " << div(a, b) << "w(" << width(div(a, b)) << ")" << endl;
126 | }
127 | return 0;
128 | }
129 | ```
130 |
131 | 위의 프로그램에서 제대로 구간 연산이 이루어지면 아래와 같은 결과를 얻을 수 있다. 여기서 width는 구간의 폭, 즉 상단과 하단의 차이를 계산하는 함수이다. 부동 소수점 연산에 의해 부동 소수점 오차가 0이 아닌 구간 폭으로 나타나고 있음을 간파 할 수 있다.
132 |
133 | output-for-test-interval-arith-RxR.txt
134 |
135 | a = 1.7
136 | b = 3.3
137 | a + b = [5,5] w (8.88178e-16)
138 | a - b = [-1.6, -1.6] w (0)
139 | a * b = [5.61,5.61] w (8.88178e-16)
140 | a / b = [0.515152,0.515152] w (1.11022e-16)
141 |
142 |
143 | Remark. 물론 1 인자 생성자를 사용하여 IR(1) / IR(9) 등과 써도 비슷한 것을 얻을 수 있지만 이러한한데 구간끼리의 연산이라고 같은 계산이 추가로 발생 해 버리는 순간 div(1, 9)이 약간 효율이 좋다.
144 |
145 |
146 | ### 하단 · 상단 · 중간 · norm
147 | 구간의 폭을 계산하는 함수 width처럼 interval 타입으로 주어진 구간에 대해서 하등의 베이스 타입 T 의 값을 반환하는 함수로 lower, upper, median, norm 가 있다. 처음 세개는 문자적인 의미로 각 구간의 하단 · 상단 · 중간 점을 반환하는 함수이다. norm이 구간이 포함 숫자의 최대 절대 값을 반환한다.
148 |
149 |
150 |
151 |
152 | ## 출처:
153 | - https://qiita.com/t_uda/items/7712671389e016d24df6
154 | - https://qiita.com/t_uda/items/e4f554b8af864b638a6d
155 | - https://qiita.com/t_uda/items/abcf31a7b1787604a4f4
156 | - https://qiita.com/t_uda/items/e08ca64b318917e6d4ab
157 |
--------------------------------------------------------------------------------
/pool.md:
--------------------------------------------------------------------------------
1 | ## Pool
2 | - 적당한 메모리를 처음부터 확보하고, 그기에서 적절한 메모리를 할당 받는다.
3 | - 고속으로 메모리를 할당할 수 있다.
4 | - 그러나 사용할 수 있는 곳이 한정되어 있다.
5 | - 대량의 작은 오브젝트를 관리해야 하는 경우에 아주 좋다.
6 | - 게임의 오브젝트 관리나 메모리 제어가 아주 중요한 곳에서 주로 사용한다.
7 | - 메모리를 확보한 순서로 메모리 해제를 하면 object_pool 이 boost::pool 보다 느리다.
8 |
9 |
10 |
11 | ## 오브젝트와 싱글톤
12 | - 적당한 메모리를 처음부터 확보하고, 그기에서 적절한 메모리를 할당 받는다.
13 | - 고속으로 메모리를 할당할 수 있다.
14 | - 그러나 사용할 수 있는 곳이 한정되어 있다.
15 | - 대량의 작은 오브젝트를 관리해야 하는 경우에 아주 좋다.
16 | - 게임의 오브젝트 관리나 메모리 제어가 아주 중요한 곳에서 주로 사용한다.
17 |
18 |
19 |
20 | ## 간단 사용 법
21 |
22 | ### 오브젝트 풀
23 |
24 | ```
25 | struct Abc
26 | {
27 | Abc() { static int no=0; cout << "Abc() :" << (m_no=++no) << endl; }
28 | ~Abc() { cout << "~Abc():" << m_no << endl; }
29 | int m_no;
30 | };
31 |
32 | boost::object_pool p;
33 | Abc* x = p.construct();
34 | Abc* y = p.construct();
35 | Abc* z = p.construct();
36 | p.destroy(y);// 명시적으로 파괴자 호출
37 | ```
38 |
39 |
40 | ### 싱글톤 풀
41 |
42 | ```
43 | // sizeof(int) 바이트 전용 할당자
44 | boost::pool<> p( sizeof(int) );
45 | int* x = (int*)p.malloc();
46 | int* y = (int*)p.malloc();
47 | int* z = (int*)p.malloc();
48 | *x = 10;
49 | p.free(z); // 명시적으로 free
50 | ```
51 |
52 |
53 |
54 | ## 참고
55 | - [boostのobject_poolをスマートポインタで利用する](http://d.hatena.ne.jp/ytakano/20100317/1268778286 )
56 |
--------------------------------------------------------------------------------
/predef.md:
--------------------------------------------------------------------------------
1 | ## 개요
2 | - Pre_defined Compiler Macros 프로젝트에서 모아 놓은 매크로로 C++ 컴파일 환경이나 타겟 환경(OS) 정보를 얻을 수 있다.
3 | - Boost 1.55 에서 추가
4 |
5 |
6 |
7 | ## OS, 컴파일러, 비주얼스튜디오 버전
8 |
9 | ```
10 | // 출처: http://d.hatena.ne.jp/osyo-manga/20131213/1386933884
11 | #include
12 | #include
13 | #include
14 |
15 | int main()
16 | {
17 | std::cout << BOOST_COMPILER << std::endl;
18 |
19 | #if BOOST_OS_WINDOWS
20 | std::cout << "OS is Windows." << std::endl;
21 | #else
22 | std::cout << "OS is not Windows." << std::endl;
23 | #endif
24 |
25 | #if BOOST_COMP_CLANG
26 | std::cout << "Compiler is Clang." << std::endl;
27 | #elif BOOST_COMP_MSVC
28 | std::cout << "Compiler is MSVC." << std::endl;
29 | #else
30 | std::cout << "Compiler is unknow." << std::endl;
31 | #endif
32 |
33 |
34 | #if BOOST_COMP_MSVC && BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(12, 0, 0)
35 | std::cout << "VC 12" << std::endl;
36 | #elif BOOST_COMP_MSVC && BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(13, 0, 0)
37 | std::cout << "VC 13" << std::endl;
38 | #endif
39 |
40 | return 0;
41 | }
42 | ```
43 |
--------------------------------------------------------------------------------
/program_options.md:
--------------------------------------------------------------------------------
1 | # Program Options
2 | [공식 문서](https://www.boost.org/doc/libs/1_73_0/doc/html/program_options.html )
3 |
4 | ## 명령 줄 인수를 boost :: program_options에 저장
5 | [출처](http://tips.hecomi.com/entry/20110210/1297353366 )
6 |
7 | `boost::program_options`을 사용하면 명령어 라인 인수를 쉽게 분석 할 수 있다.
8 |
9 | ### 사용법
10 | 한 가지 방법을 정리해 보았다.
11 | ```
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 | using namespace std;
19 | using namespace boost::program_options;
20 |
21 | int main(int argc, char* argv[])
22 | {
23 | // 옵션 정의를 한다
24 | // 뒤에서 합칠 수 있다.
25 | options_description options1("옵션 그룹 1");
26 | options_description options2("옵션 그룹 2");
27 | options_description options3("옵션 그룹 3");
28 | options_description options4("옵션 그룹 4");
29 |
30 | // 옵션은 add_options() 이후에 operator()를 연결시켜서 추가
31 | // 「,」의 앞에 정식 이름, 뒤에 줄임 이름을 적는다(생략 가능)
32 | options1.add_options()
33 | ("option1", "옵션 1")
34 | ("option2,b", "옵션 2")
35 | ;
36 |
37 | // option=*** 으로 받는 값의 타입을 설정할 수 있다.
38 | // 또 default_value 로 기본 값도 설정 가능
39 | options2.add_options()
40 | ("option3,c", value(), "옵션3")
41 | ("option4,d", value(), "옵션4")
42 | ("option5,e", value()->default_value(10), "옵션5")
43 | ;
44 |
45 | // option=*** 의 값을 받는 변수를 지정할 수도 있다
46 | int option6;
47 | string option7;
48 | options3.add_options()
49 | ("option6,f", value(&option6), "옵션6")
50 | ("option7,g", value(&option7), "옵션7")
51 | ;
52 |
53 | // 같은 옵션을 복수 사용하여 저장할 수도 있다
54 | options4.add_options()
55 | ("option8", value >(), "옵션8")
56 | ;
57 |
58 | // 옵션 정의를 모을 수 있다
59 | options1.add(options2).add(options3);
60 |
61 | // 옵션 값을 읽는 변수
62 | variables_map values;
63 |
64 | // 다양한 예외를 잡을 수 있다(예는 catch 블럭 내에 기술한다)
65 | try {
66 | // parse_command_line 에서 명령어 라인 인수를 parse 하고,
67 | // 이 결과를 store에서 variable_maps 에 저장한다
68 | store(parse_command_line(argc, argv, options1), values);
69 |
70 | // 명령어 라인 인수뿐만 아닌 외부 파일에서도 옵션을 읽을 수 있다
71 | // 이 때는 parse_config_file을 사용하여 parse 한다
72 | ifstream ifs("config.txt");
73 | store(parse_config_file(ifs, options4), values);
74 |
75 | // notify를 호출하여 values에 값을 저장한다
76 | notify(values);
77 |
78 | // 옵션 유무는 count로 조사한다
79 | if (!values.count("option1") && !values.count("option2")) {
80 | // options_description는 표준 출력에 던질 수 있다
81 | cout << options1 << endl;
82 | cout << options4 << endl;
83 | }
84 | if (values.count("option1")) {
85 | cout << "option1 이 지정 되었다" << endl;
86 | }
87 | if (values.count("option2")) {
88 | cout << "option2 이 지정 되었다" << endl;
89 | }
90 |
91 | // as<타입 이름>() 으로 값을 얻을 수 있다
92 | cout << "option3: " << values["option3"].as() << endl;
93 | cout << "option4: " << values["option4"].as() << endl;
94 | cout << "option5: " << values["option5"].as() << endl;
95 |
96 | cout << "option6: " << option6 << endl;
97 | cout << "option7: " << option7 << endl;
98 |
99 | // 복수의 데이터를 받은 것도 사용 가능
100 | cout << "option8: ";
101 | vector option8( values["option8"].as >() );
102 | for (vector::iterator it = option8.begin(); it != option8.end(); ++it) {
103 | cout << *it << " ";
104 | }
105 | cout << endl;
106 |
107 | } catch (exception &e) {
108 | // 저장 되지 않은 것을 values["***"] 를 호출하면
109 | // boost::bad_any_cast: failed conversion using boost::any_cast
110 | // 가 표시된다.
111 | // 정의 되지 않은 옵션 --*** 을 호출하면
112 | // unknown option ***
113 | // 가 표시된다
114 | cout << e.what() << endl;
115 | }
116 |
117 | return 0;
118 | }
119 | ```
120 |
121 | ### 결과
122 |