본문 바로가기

프로그래밍

[펌] Boost 로 C++0x의 라이브러리 「TR1」을 미리 사용 해 보자 (3)

[중급] N개 이상의 요소를 정리하는「tuple」


서두

 C++의 새로운 규격 「C++0x」에서는 언어와 라이브러리의 양면으로부터 편리한 기능이 추가됩니다.「TR1」(Technical Report 1)은 C++0x의 라이브러리 부로 표준 C++에 새롭게 추가되는 라이브러리의 상당수는 Boost 중에서 선택된 것입니다. 2008년 봄에 릴리스가 예정되어 있 Visual Studio 2008에도 추가 패키지로서 공급된다라는 정보를 얻고 있습니다.

 TR1에 수록된 클래스/함수 중에서 몇 개 인가를 픽업, 그 개요와 사용법을 예습해 둡시다. 제 3회는 tuple입니다.

t

tuple(1/2)

표준 C++라이브러리에는 두 개의 요소를 가지는 구조체: pair 정의되고 있습니다.

   pair

  1. #include <iostream>

  2. #include <string>

  3. #include <utility> // pair 


  4. using namespace std;


  5. int main()

  6. {

  7.    const int N = 3;

  8. pair phone[N];


  9. phone[0] = pair( "경찰" , 110); // 대입 1

  10. phone[1].first = "시보" ; // 대입 2

  11. phone[1].second = 117;

  12. phone[2] = make_pair( "소방" , 119); // 대입3 


  13. phone[0].swap(phone[2]); // 교환 


  14. for ( int i = 0; i < N; ++i ) {

  15. cout << phone[i].first << ':' << phone[i].second << endl;

  16. }

  17. }

 실행 결과
소방:119
시보:117
경찰:110

 

pair 로 묶을 수 있는 요소 수는 2개로 한정되기 때문에 그 이상의 요소 수를 정리하는 것은 많이 귀찮습니다.

    pair 에서 억지로 3요소 사용

  1. #include <iostream>

  2. #include <string>

  3. #include <utility> // pair 


  4. using names pace std;


  5. // pair 와 string 의 pair

  6. struct musician : pair,string> {

  7. typedef pair,string> base;

  8. musician(string f, string m, string l) : base(make_pair(f,m),l) {}

  9. };


  10. ostream& operator <<(ostream& st ream, const musician& m) {

  11. return stream << m.first.first << ' '

  12. << m.first.second << ' '

  13. << m.second;

  14. }


  15. int main()

    {

  16. musician wam( "Wolfgang" ,"Amadeus" ,"Mozart" );

  17. musician jsb( "Johann" ,"Sebastian" ,"Bach" );

  18. cout << wam << endl << jsb << endl;

  19. }


실행 결과

Wolfgang Amadeus Mozart

Johann Sebastian Bach


TR1 에서 제공 되는 tuple 은 두 개 묶음인 pair 를 확장 하여 임의의 N개의 요소를 묶음으로 할 수 있습니다(N은 구현 의존 boost1.34.1 에서는 최대 9개였습니다).

     tr1::tuple판 '음악가' 

  1. #include <iostream>

  2. #include <string>

  3. #include <boost/tr1/tuple.hpp>  // tuple 


  4. using name space std;


  5. struct musician : tr1::tuple<string,string,string> {

  6. typedef tr1::tuple<string,string,string> base;

  7. musician(string f, string m, string l) : base(f,m,l) {}

  8. };


  9. ostream& operator <<(ostream& stream, const musician& m) {

  10. return stream << tr1::get<0>(m) << ' '

  11. << tr1::get<1>(m) << ' '

  12. << tr1::get<2>(m);

  13. }


  14. int main()

    {

  15. musician wam( "Wolfgang" ,"Amadeus" ,"Mozart" );

  16. musician jsb( "Johann" ,"Sebastian" ,"Bach" );

  17. cout << wam << endl << jsb << endl;

  18. }

 le(2/2)
  

tuple(2/2)

 

요소의 접근

tuple 의(0을 기점으로서) 제 n번째의 요소는 함수 get 을 개입시켜 접근 합니다. 다만 n은 정수가 아니면 안됩니다. get은 참조를 돌려주므로 좌변 값으로 이용하는 것으로 요소에 대입이 가능합니다.

     get에 의한 참조와 대입

  1. #include <iostream>

  2. #include <string>

  3. #include <boost/tr1/tuple.hpp> // tuple 


  4. using namespace std;


  5. int main()

    {

  6. tr1::tuple exam;

  7. tr1::get<0>(exam) = "Steve" ;

  8. tr1::get<1>(exam) = 567;

  9. tr1::get<2>(exam) = tr1::get<1>(exam) / 5.0;

  10. cout << tr1::get<0>(exam) << "너의" 

  11. " 득점=" << tr1::get<1>(exam) <<

  12. " 평균=" << tr1::get<2>(exa m) << endl;

  13. // Steve너의 득점=567 평균=113.4 

  14. }

 

 

  pair 와의 인터페이스의 통일 때문에  pair에 대해서도 함수  get  적용할 수 있습니다.

     pair에 대해서 get 한다

  1. #include <iostream>

  2. #include <string>

  3. #include <utility>  // pair

  4. #include <boost/tr1/tuple.hpp>// tuple 


  5. using namespace std;


  6. int main()

    {

  7. pair police = make_pair( "???" , 110);

  8. tr1::get<0>(police) = "순경" ;


  9. cout << tr1::get<0>(police) << ':' << tr1::get<1>(police) << endl;

  10. }


 

일괄 대입 / 일괄 참조

pair 에 있어서의 make_pair 와 같이 tuple 에는 함수 make_tuple  준비되어 있습니다.
또, 함수  tie 에 의해서 복수의 변수에 일괄해 읽어낼 수 있습니다.

     make_pair/tie

  1. #include <iostream>

  2. #include <string>

  3. #include <boost/tr1/tuple.hpp>   // tuple 


  4. using namespace std;


  5. int main()

    {

  6. tr1::tuple exam;

  7. exam = tr1::make_tuple( "Steve" , 567, 567/5.0);

  8. string name;

  9. double mean;

  10. // tie:사용하지 않는 요소에는 ignore(무시)를 지정 할 것 

  11. tr1::tie(name, tr1::ignore, mean) = exam;

  12. cout << name << "너의 평균점은" << mean << endl;

  13. // Steve 너의 평균점은113.4 

  14. }


 

비교

tuple 의 비교 연산 == , != , <, <= , >, >= 은 각 요소를 왼쪽에서 순서 대로 비교합니다. 비교 도중에 진위가 확정하면 그 이후의 비교는 행해지지 않습니다.

      tuple의 비교는 shortcut 된다

  1. #include <iostream>

  2. #include <boost/tr1/tuple.hpp>  // tuple 


  3. using namespace std;


  4. struct Value

    {

  5. int n_;

  6. Value( int n) : n_(n) {}

  7. };


  8. bool operator ==( const Value& x, const Value& y)

    {

  9. bool result = ( x.n_ == y.n_ );

  10. cout << x.n_ << (result ? "==" :"!=" ) << y.n_ << endl;

  11. return result;

  12. }


  13. bool operator <( const Value& x, const Value& y)

    {

  14. bool result = ( x.n_ < y.n_ );

  15. cout << x.n_ << (result ? "<" :">=" ) << y.n_ << endl;

  16. return result;

  17. }


  18. int main()

    {

  19. typedef tr1::tuple triple;

  20. triple x(12,34,56);

  21. triple y(12,43,56);

  22. // 제2요소까지의 비교로 진위가 확정 되기 때문에 

  23. // 제3요소의 비교는 행해지지 않는다 

  24. cout << "x == y :" << boolalpha << (x == y) << endl;

  25. cout << "x < y :" << boolalpha << (x < y) << endl;

  26. }


실행 결과

12==12

34!=43

x == y : false 

12>=12

12>=12

34<43

x < y : true

 

 

tuple_size,tuple_element

tuple_size::value  Tuple의 요소수,
tuple_element::type  Tuple의 N번째의 요소의 형태가 됩니다.

 

    tuple_size, tuple_element

  1. #include <iostream>

  2. #include <string>

  3. #include <boost/tr1/tuple.hpp>   // tuple 


  4. using namespace std;


  5. // Tuple의 요소 

  6. template <<span style="font-family:굴림체; font-size:9pt; color:#0000ff;"> typename Tuple>

  7. int members( const Tuple&)

    {

  8. return tr1::tuple_size::value;

  9. }


  10. // Tuple의 N번째를 '+' 한다

  11. template <<span style="font-family:굴림체; font-size:9pt; color:#0000ff;"> int N, typename Tuple>

  12. typename tr1::tuple_element::type

  13. plus( const Tuple& x, const Tuple& y)

    {

  14. return tr1::get(x) + tr1::get(y);

  15. }


  16. int main()

    {

  17. tr1::tuple t1( "Hello" ,12);

  18. tr1::tuple t2( "World" ,34);

  19. cout << members(t1) << " members." << endl;

  20. cout << plus<0>(t1,t2) << endl;

  21. cout << plus<1>(t1,t2) << endl;

  22. }


실행 결과

2 members.

HelloWorld

46

 

 

번역 후기........

번역된 글을 퍼 갈 때는 꼭 아래의 글을 같이 복사 해 주세요.

번역은 원 저자에게 허락을 받은 것은 아니므로 상업적으로 사용할 경우에는 꼭 원저자에게 허락을 받기를 바랍니다.

출처 : http://codezine.jp/a/article/aid/2134.aspx

 

번역 :   choi_2.jpg   최흥배 ( jacking75@gmail.com ).

             (주) 다이슨 파이퍼스튜디오에서 서버 프로그래머로 근무 중.