레이블이 STL인 게시물을 표시합니다. 모든 게시물 표시
레이블이 STL인 게시물을 표시합니다. 모든 게시물 표시

11월 29, 2016

rdbuf() : 서로 다른 두 스트림을 연결


std::ios::rdbuf()

일부 derived stream class(stringstream or fstream 등)는 객체 생성 시에 associated 된 internal stream buffer를 가진다. rdbuf는 stream의 associated stream buffer를 변경하는 함수로, stream buffer 자체에는 아무련 영향을 주지 않는다.

cin/ifstream, 혹은 cout/ofstream 등, 서로 다른 두 stream을 한 스트림에서 다른 스트림으로 리디렉시키는데 사용한다. 예를 들어 어떤 프로그램에서 input을 console과 cin을 통해 입력받는데, input을 입력받는 코드 부분을 수정하지 않고 file stream을 통해서 입력을 받도록 프로그램을 수정하고 싶을 때 유용하게 사용할 수 있다.

(1) streambuf* rdbuf() const;
(2) streambuf* rdbuf(streambuf* sb);

(1) accessor. 현재 stream의 associated streambuf의 포인터를 리턴.

(2) mutator. 현재 stream의 associated streambuf를 sb로 바꾸고 stream의 error state flags를 초기화. 이전 associated streambuf의 포인터를 리턴.


예제




reference

11월 17, 2016

Random Access Iterator


Random-access Iterator?

자신이 가르키고 있는 element과 연관되어 있는 임의의 position에 접근하여 포인터와 같은 functionality 를 제공할 수 있는 iterator. 모든 Random-access iterator 는 bidirectional iterator이며, 어떤 element에도 constant time으로 접근할 수 있음.


Funtionalities of Random-access Iterator

  • Bidirectional Iterator 가 제공하는 모든 기능
  • Arithmetic operator ex) it1+n, n+it1, it1-n, it1-it2
  • Inequality relation operator ex) it1<it2, it2>it1, it1<=it2, it1>=it2
  • Compound assignment operator ex) it1+=n, it1-=n
  • Offset dereference operator ex) it1[n]

reference

Bidirectional Iterator


Bidirectional Iterator

유효한 범위의 sequance of element에서 begin, end 양방향의 element에 모두 access 가능한 iterator. 모든 Bidirectional iterator 는 Forward Iterator.


Funtionalities of Bidirectional Iterator

  • Default/copy/copy-assignment constructible ex) X it1; , X it2(it1); , it2 = it1;
  • In/Equality operator ex) it1==it2, it1!=it2
  • Dereference as R-value ex) *it1, it1->m
  • Dereference as L-value ex) *it1 = t
  • Increment ex) ++it1, it1++
  • Decrement ex) --it1, it1--
  • L-value are swappable ex) swap(it1, it2)

X는 Bidirectional iterator type, m은 가르키는 멤버, t는 iterator가 가르키는 타입의 object.


reference

6월 23, 2016

seekg() VS seekp(), tellg() VS tellp()


  • tellg()
  • get pointer의 현재 위치를 반환함. tellg() 는 input streams 와 함께 쓰이며, stream의 현재 포인터의 'get' position 을 반환함(get pointer의 현재 위치). get pointer는 input sequence에서 다음 input operation이 일어날 위치를 가르킴.

    • pos_type tellg()

  • tellp()
  • put pointer의 현재 위치를 반환함. tellp()는 output streams와 함께 쓰이며, stream의 현재 포인터의 'put' position을 반환함(put pointer의 absolute position을 반환). put pointer는 output sequence에서 다음 output operation이 일어날 위치를 가르킴.

    • pos_type tellp()

  • seekg
  • get pointer의 위치를 변경함. get pointer는 input stream과 관련된 pointer로, input stream과 연결된 source에서 읽어올 다음 위치를 가르킴.

    • istream& seekg(pos) pos로 pointer를 옮김.
    • pos는 absolute value(the value counting from begin of the file).

    • istream& seekg(offset, direction)
    • offset은 stream의 direction으로부터 offset을 direction은 offset을 counting할 기준점. (ios_base::beg, ios_bas::cur, ios_base::end 등이 존재.)

  • seekp
  • put pointer의 위치를 변경함. put pointer는 output stream과 관련된 pointer로, stream object의 output(put or write) file pointer의 위치를 가르킴. 대부분의 경우 stream object의 input file pointer의 위치도 함께 변경시킴.

    • ostream& seekp(pos) pos로 pointer를 옮김.
    • ostream& seekp(offset, direction)

example


output



Reference

4월 21, 2016

multi-dimensional vector로 2차원 행렬 구현하기


vector를 요소로 갖는 벡터를 선언하여 2-dim array를 구현 가능. 이 경우, 각각의 row는 별도의 vector 이므로, n x n 으로 딱 떨어지는 행렬 뿐 아니라 row마다 서로 다른 크기의 column을 가지게 하는 것도 가능.

예제




단, method1 의 경우 column의 크기가 커지는 경우 vector 재할당이 발생해 효율이 떨어질 수 있음. 특히 새로운 row의 추가로 인한 vector 재할당은 단순히 그 row만 영향을 받는게 아니라 전체 row에 대해 재할당이 일어나기 때문에, 각 row 별로 vector 들이 전부 재할당 되어 더욱 심각한 비효율을 초래함.



결과

========================
0 1 2
3 4 5

========================
1 2 3
4 5 6

========================
0 0 0
0 0 0



reference

4월 15, 2016

STL unordered map

associative container. 각 element는 Hash 함수를 통해 bucket이라는 하위 시퀀스로 약하게 정렬됨. bucket 간의 탐색 시간은 constant, bucket 내에서의 탐색 시간은 linear함.
요소를 제거하는 경우 해당 요소의 iterator는 무효화되지만, 그외 다른 iterator는 유효함.

사용법

  • key와 element의 std::pair를 element로 가짐
  • iterator를 사용한 sequential한 반복 탐색, range 반복 탐색 가능(begin(), end())
  • 요소 삽입은 insert(..) 혹은 emplace(..) 사용
  • operator[key]를 이용한 random access 가능. 만약 존재하지 않는 key에 접근하는 경우 해당 key를 갖는 새로운 element 생성
  • find(key)로 탐색 가능. 반환형은 해당 element의 iterator
  • count(key) vs size(): count는 지정된 key를 갖는 element의 수를 반환, size는 map 내의 element 총개수를 반환. unorded_map의 경우 모두 다른 key 값을 갖기 때문에, 해당 key의 element가 있으면 1, 없으면 0 반환
  • erase(..): key나 iterator, ranged iterator로 지울 element 선택 가능. 각 경우에 따라 반환형이 달라지는데, key의 경우 지워진 element의 개수, iterator의 경우 지워진 element 중 마지막 element의 iterator를 반환
  • clear(): 모든 element의 destructor를 부르고 container에서 drop시킴. size는 0이 됨

예시



references

3월 31, 2016

C++ 11 이후 새로운 random 함수 표준

MT(Mersenne Twister 메르센 트위스터)

  • 유사 난수 생성기. 기존 생성기의 문제점을 피하며 매우 질이 좋은 난수를 빠르게 생성 가능.
  • 32bit(MT19937), 또는 64bit(MT19937_64) 크기의 난수 생성 가능.
  • 난수의 특성(주기, 난수의 범위 등)을 알고 있으면 그 뒤 나올 난수를 예측 가능하기 때문에 암호학적으로 안전한 생성기는 아님.
  • 예시1
  • 출력 화면
  • 예시2 - C++ 표준을 좀 더 다양하게 사용한 개선 코드
  • 출력 화면

WELL

  • MT의 개발자가 10년 후에 고안한 난수 발생 알고리즘.
  • MT보다 40% 가량 빠르며 코드도 더 간단하다고 함.
  • 분포도에 따라 WELLS512, WELLS1024, WELLS19947(숫자가 커질 수록 분포도↑) 등 다양한 종류가 존재.

references

3월 22, 2016

move semantic 구현

move constructor와 move assignment operator를 정의

move constructor를 정의

  • move constructor
  • move constructor의 경우moved-to-obj의 리소스를 해제하고 그 자리에 move-from-obj의 리소스를 배정. move-from-obj의 리소스 참조를 끊어줌.(ex. pointer를 nullptr로 변경)

  • move assignment operator
  • move-to-obj와 move-from-obj가 동일한 객체인지 검사하고 동일하지 않은 객체일 경우 이동 작업을 진행.



코드의 간략화

move assignment operator를 이용해 move constructor의 중복 코드를 제거할 수 있음.


기타

  • move constructor의 move-from-obj destruct
  • 일반적으로, move constructor에서 move-from-obj를 destruct 해주지는 않음. 그러나 move constructor가 불린 후 꼭 move destructor가 뒤따라 불리는데, 이건 move constructor가 move-from-obj를 destruct해서가 아니라 함수에서 임시로 생성됐던 객체가 move constructor가 불린 후 life time이 끝나 해제가 된 것. move constructor에서 move-from-obj의 destruct해야할 어떤 책임도 없음.


rvalue를 param.로 받는 함수를 overloading.

perfect forwarding?


references

1월 29, 2016

ch15. Input/Output using stream classes

0. Overview

  • C++11부터 string stream과 file stream이 rvalue와 move semantic을 지원.
순서



1. Background of I/O streams

  1. stream objects
  2. output : stream으로 흘러들어오는 데이터
    input : stream에서 흘러나가는 데이터

  3. stream classes
  4. class istream : 데이터를 읽는데 사용되는 input stream
    class ostream : 데이터를 쓰는데 사용되는 output stream

  5. global stream objects
    • cin
    • cout
    • cerr
    • clog
  6. stream operators
  7. manipulators
  8. stream을 조작하기 위해 사용되는 특수한 object. input을 읽어들이는 방식이나 output이 출력되는 방식을 바꾸는 유일한 방법임.

  9. a simple example


2. Fundamental stream classes and objects

  1. Classes and class hierarchy
  2. //rev header file including structure
    IOStream library는 철저히 각자의 책임을 분리하는 방향으로 설계됨. basic_ios를 상속받는 클래스들은 오직 formatting data만을 처리함. characters의 읽기와 쓰기는 basic_ios의 subobjects인 stream buffers에 의해 수행됨.

  3. Global stream objects
    • cin - istream
    • cout - ostream
    • cerr - ostream
    • clog - ostream
  4. Header files
  5. application programmer는 <iosfwd>를 include하는 것으로 충분하며, input, output functions을 사용하기 위해 필요에 따락 각각 <istream>과 <ostream>을 include한다.
    일반적으로 헤더 파일에는 꼭 필요한 파일만 include 한다. 특히 헤더파일에는 <iosfwd>만 include하고, 이에 대응되는 implementation 파일에 헤더 파일을 include해서 완전한 정의를 하도록 한다.

3. Standard Stream Operators << and >>

bit shift 연산자인 <<와 >>를 overloading 하여 입출력 연산자로 사용. void와 nullptr_t을 제외한 거의 모든 data type에 대해 overloading 되어있음.

  1. Output Operator <<
  2. C++11에서 같은 stream object를 concurrent output에 사용하는 것이 가능하지만 이 경우 출력이 서로 섞일 수 있음.

  3. Input Overator >>
  4. 두번째 param.는 non const value여야 함.
    C++11에서 같은 stream object를 concurrent input에 사용하는 것이 가능하지만 이 경우 입력이 서로 섞일 수 있음.

  5. Input/Output Of Special Types
    • Numeric type
    • input 읽을 때 적어도 한자리 숫자로 시작해야함. 그렇지 않으면 value는 0이 되고 failbit이 set 됨.

    • Type bool
    • false는 0으로, true는 1로 converting.

    • Types char and wchar_t
    • leading whitespace is skipped by default. whitespace까지 읽고 싶을 때는 flag _skipws_를 clear하거나 member function get()을 사용.

    • Type char *
    • read wordwisely. leading whitespace is skipped by default. 다음 whitespace 나 end-of-file을 만날 때까지 읽음. flag _skipws_를 통해 leading whitespace를 skip할지 정할 수 있음. 만약 읽을 문자의 숫자를 지정하고 싶다면 setw(..) 를 사용.

      char buffer[81]; std::cin >> std::setw(81) >> buffer;
      char * 를 사용하기보다 std::string 을 사용할 것을 권장. 이 경우 getline()을 통해 line 단위로 입력이 가능.

    • Type void *
    • void * 를 사용 시 pointer 출력(memory address 출력)도 가능.
      char * cstring = "hello"; std::cout << static_cast<void *>(cstring) << std::endl; // cstring의 주소가 출력됨
    • Stream Buffers
    • C++ I/O/ streams를 이용해서 파일을 복사하는 가장 빠른 방법. 15.14.3 참조.

    • User-Defined Types
    • Monetary and Time Values

4. State of Streams

Stream에는 I/O가 성공했는지 실패했는지, (실패한 경우) 실패한 이유 등이 기록된 state가 있음.

  1. Constants for the State of Streams
    • goodbit
    • eofbit
    • failbit
    • badbit

    flags는 class basic_ios 에 포함되어있기 때문에 class basic_istream 또는 class basic_ostream 의 모든 객체에 존재한다. 그러나 stream buffer는 아무런 state flag를 가지지 않는데, 이는 하나의 stream buffer 가 여러개의 stream 객체에서 사용될 수 있기 때문.

  2. Member Functions Accessing the State of Streams
  3. error bits는 언제나 명시적으로 clear 해줘야 함.

  4. Stream State and Boolean Conditions
  5. operator >> 의 default 설정은 leading whitespace를 skip함. 이런 whitespace skip을 막고 싶다면 stream member function의 put()과 get() 을 사용할 수 있으며, 이보다 나은 방법으로 istreambuf_iterator를 이용해 I/O 필터를 구현할 수도 있음.

    if ( !(std::cin >> x)) { // !뒤의 괄호 위치에 주의
    // the read failed
    ...
    }

  6. Stream State and Exceptions
  7. backward compatibility를 위해 stream는 exception을 던지지 않는 것이 default로 설정되있지만, 모든 flag에 대해 flag가 set 되었을 때 exception을 던지게 설정할 수 있음.
    exception은 보다 더 unexpectied situation에서 사용되어야 함. input/output 과정에서의 format error와 같은 error는 정상으로 간주되며, exception 처리 보다는 state flag를 통한 처리 방법이 더 좋은 방법임.

5. Standard Input/Output Functions

formatted operator unformatted operator
<< / >> get(..), getline(..), read(..)
put(..), write(..)
skips whitespaces never skips leading whitespaces
  1. Member functions for input
    • get(c, num)
    • get(c, num, t)
    • getline(str, num)
    • getline(str, num, t)
    • read(str, num)
    • readwome(str, num)
    • etc..

    그러나 C-strings를 읽을 때는 위의 함수들보다 operator >>를 사용하는 것이 더 안전함.
    character나 string을 읽을 때 istream member function을 사용하는 것보다 stream buffer를 통해 바로 접근하는 것이 더 유리할 때가 많은데, 이는 stream buffer member function은 input 과정에서 (istream class와 달리) sentry object를 생성하지 않아 construction overhead가 없기 때문.

  2. Example Uses
  3. sentry objects
  4. I/O stream operators 와 functions에서 I/O는 I/O preprocessing, 실제 I/O 작업, I/O postprocessing의 3단계에 걸쳐 수행됨. sentry class는 이를 위한 보조 클래스의 일종으로, stream과 관련된 여러 state에 관한 정보를 담고 있음. 만약 I/O operator를 stream buffer에 바로 적용하기 위해선 sentry object를 먼저 생성해줘야 함.

Manipuators

Manipulator for streams는 standard I/O operators에 적용되어 stream의 특성을 바꿔주는 object를 말함. arguments를 가지는 standard manipulators는 헤더파일 <iomanip>에 정의되어 있으며, 이를 사용하기 위해선 이 헤더 파일을 include해야함.

  1. Overview of All Manipulators
    • endl
    • ends
    • flush
    • skipws
    • noskipws
    • setw
    • setfill
    • boolalpha
    • showpos
    • dec
    • hex
    • ...
  2. How Manipulators Work
  3. manipulator가 어떻게 작동할지는 구현하기에 따라서 달라지며, 구현 과정에 있어서 표준적인 방법은 존재하지 않음.

  4. User-Defined Manipulatrs

Formatting

  1. Format Flags
  2. Input/Output Format of Boolean Values
  3. Field width, Fill Character, and Adjustment
  4. Positive Sign and Uppercase Letters
  5. Numeric Base
  6. Foating-Point Notation
  7. General Formatting Definitions


출처

the c++ standard library a tutorial and reference by Nicolai M. Josuttis

12월 30, 2015

C++ 추천도서


도서

  1. Effective C++
  2. More Effective C++
  3. Effective C++ STL
  4. Effective Modern C++
  • Efficient C++ : C++ 최적화에 대한 설명, 실험 등
  • The C++ Programming Language 4th, Bjarne Stroustrup : C++ 이라는 언어의 철학에 좀 더 가까운..

참고



12월 16, 2015

C++11 lambda expression



  • Syntex of lambda
[caps]  {
    function_contents;
};
    또는
[caps]  (params)  (mutable) (throwSpec) (->retType)   {
    function_contents;
};

    • caps: captures. 외부의 변수 값을 람다 내부에서 사용할 수 있게 함
               [=] : 람다 외부의 값을 value 형식으로 전달
               [&] : 람다 외부의 값을 reference 형식으로 전달
    • params: 람다는 일반 함수와 마찬가지로 파라미터 값을 받을 수 있는데, 이와 같이 파라미터 값을 람다 내부로 건네주는데 사용 
    • mutable : 람다에 mutable 선언시 value 로 전달된 captures를 람다 내부에서 수정할 수 있으며 수정된 값은 람다 내부에서 유지. (value로 전달 됐으므로 람다 밖에서는 수정된 값이 적용되지 않음)
    • throwSpec 
    • retType: 람다는 일반함수와 마찬가지로 값을 리턴할 수 있는데, 이 리턴값의 type을 지정하는데 사용 
    • function_contents: 람다가 수행하는 내용



  • ex)
int x = y = 1;
auto l = [=x, &y] -> bool {
    if ( ++x == ++y )
        return true;
    else
        return false;
};
// true 리턴, x는 1, y는 2 값으로 변경.
       
  • lambda의 장점


  • lambda의 한계