[중급] 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
#include <iostream>
#include <string>
#include <utility> // pair
using namespace std;
int main()
{
const int N = 3;
pair phone[N];
phone[0] = pair( "경찰" , 110); // 대입 1
phone[1].first = "시보" ; // 대입 2
phone[1].second = 117;
phone[2] = make_pair( "소방" , 119); // 대입3
phone[0].swap(phone[2]); // 교환
for ( int i = 0; i < N; ++i ) {
cout << phone[i].first << ':' << phone[i].second << endl;
}
}
실행 결과
소방:119
시보:117
경찰:110
pair 로 묶을 수 있는 요소 수는 2개로 한정되기 때문에 그 이상의 요소 수를 정리하는 것은 많이 귀찮습니다.
pair 에서 억지로 3요소 사용
#include <iostream>
#include <string>
#include <utility> // pair
using names pace std;
// pair 와 string 의 pair
struct musician : pair,string> {
typedef pair,string> base;
musician(string f, string m, string l) : base(make_pair(f,m),l) {}
};
ostream& operator <<(ostream& st ream, const musician& m) {
return stream << m.first.first << ' '
<< m.first.second << ' '
<< m.second;
}
int main()
{
musician wam( "Wolfgang" ,"Amadeus" ,"Mozart" );
musician jsb( "Johann" ,"Sebastian" ,"Bach" );
cout << wam << endl << jsb << endl;
}
실행 결과
Wolfgang Amadeus Mozart
Johann Sebastian Bach
TR1 에서 제공 되는 tuple 은 두 개 묶음인 pair 를 확장 하여 임의의 N개의 요소를 묶음으로 할 수 있습니다(N은 구현 의존 boost1.34.1 에서는 최대 9개였습니다).
tr1::tuple판 '음악가'
#include <iostream>
#include <string>
#include <boost/tr1/tuple.hpp> // tuple
using name space std;
struct musician : tr1::tuple<string,string,string> {
typedef tr1::tuple<string,string,string> base;
musician(string f, string m, string l) : base(f,m,l) {}
};
ostream& operator <<(ostream& stream, const musician& m) {
return stream << tr1::get<0>(m) << ' '
<< tr1::get<1>(m) << ' '
<< tr1::get<2>(m);
}
int main()
{
musician wam( "Wolfgang" ,"Amadeus" ,"Mozart" );
musician jsb( "Johann" ,"Sebastian" ,"Bach" );
cout << wam << endl << jsb << endl;
}
le(2/2)
tuple(2/2)
요소의 접근
tuple 의(0을 기점으로서) 제 n번째의 요소는 함수 get 을 개입시켜 접근 합니다. 다만 n은 정수가 아니면 안됩니다. get은 참조를 돌려주므로 좌변 값으로 이용하는 것으로 요소에 대입이 가능합니다.
get에 의한 참조와 대입
#include <iostream>
#include <string>
#include <boost/tr1/tuple.hpp> // tuple
using namespace std;
int main()
{
tr1::tuple exam;
tr1::get<0>(exam) = "Steve" ;
tr1::get<1>(exam) = 567;
tr1::get<2>(exam) = tr1::get<1>(exam) / 5.0;
cout << tr1::get<0>(exam) << "너의"
" 득점=" << tr1::get<1>(exam) <<
" 평균=" << tr1::get<2>(exa m) << endl;
// Steve너의 득점=567 평균=113.4
}
또 pair 와의 인터페이스의 통일 때문에 pair에 대해서도 함수 get 을 적용할 수 있습니다.
pair에 대해서 get 한다
#include <iostream>
#include <string>
#include <utility> // pair
#include <boost/tr1/tuple.hpp>// tuple
using namespace std;
int main()
{
pair police = make_pair( "???" , 110);
tr1::get<0>(police) = "순경" ;
cout << tr1::get<0>(police) << ':' << tr1::get<1>(police) << endl;
}
일괄 대입 / 일괄 참조
pair 에 있어서의 make_pair 와 같이 tuple 에는 함수 make_tuple 이 준비되어 있습니다.
또, 함수 tie 에 의해서 복수의 변수에 일괄해 읽어낼 수 있습니다.
make_pair/tie
#include <iostream>
#include <string>
#include <boost/tr1/tuple.hpp> // tuple
using namespace std;
int main()
{
tr1::tuple exam;
exam = tr1::make_tuple( "Steve" , 567, 567/5.0);
string name;
double mean;
// tie:사용하지 않는 요소에는 ignore(무시)를 지정 할 것
tr1::tie(name, tr1::ignore, mean) = exam;
cout << name << "너의 평균점은" << mean << endl;
// Steve 너의 평균점은113.4
}
비교
tuple 의 비교 연산 == , != , <, <= , >, >= 은 각 요소를 왼쪽에서 순서 대로 비교합니다. 비교 도중에 진위가 확정하면 그 이후의 비교는 행해지지 않습니다.
tuple의 비교는 shortcut 된다
#include <iostream>
#include <boost/tr1/tuple.hpp> // tuple
using namespace std;
struct Value
{
int n_;
Value( int n) : n_(n) {}
};
bool operator ==( const Value& x, const Value& y)
{
bool result = ( x.n_ == y.n_ );
cout << x.n_ << (result ? "==" :"!=" ) << y.n_ << endl;
return result;
}
bool operator <( const Value& x, const Value& y)
{
bool result = ( x.n_ < y.n_ );
cout << x.n_ << (result ? "<" :">=" ) << y.n_ << endl;
return result;
}
int main()
{
typedef tr1::tuple triple;
triple x(12,34,56);
triple y(12,43,56);
// 제2요소까지의 비교로 진위가 확정 되기 때문에
// 제3요소의 비교는 행해지지 않는다
cout << "x == y :" << boolalpha << (x == y) << endl;
cout << "x < y :" << boolalpha << (x < y) << endl;
}
실행 결과
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
#include <iostream>
#include <string>
#include <boost/tr1/tuple.hpp> // tuple
using namespace std;
// Tuple의 요소 수
template <<span style="font-family:굴림체; font-size:9pt; color:#0000ff;"> typename Tuple>
int members( const Tuple&)
{
return tr1::tuple_size::value;
}
// Tuple의 N번째를 '+' 한다
template <<span style="font-family:굴림체; font-size:9pt; color:#0000ff;"> int N, typename Tuple>
typename tr1::tuple_element::type
plus( const Tuple& x, const Tuple& y)
{
return tr1::get(x) + tr1::get(y);
}
int main()
{
tr1::tuple t1( "Hello" ,12);
tr1::tuple t2( "World" ,34);
cout << members(t1) << " members." << endl;
cout << plus<0>(t1,t2) << endl;
cout << plus<1>(t1,t2) << endl;
}
실행 결과
2 members.
HelloWorld
46
번역 후기........
번역된 글을 퍼 갈 때는 꼭 아래의 글을 같이 복사 해 주세요.
번역은 원 저자에게 허락을 받은 것은 아니므로 상업적으로 사용할 경우에는 꼭 원저자에게 허락을 받기를 바랍니다.
출처 : http://codezine.jp/a/article/aid/2134.aspx
번역 : 최흥배 ( jacking75@gmail.com ).
(주) 다이슨 파이퍼스튜디오에서 서버 프로그래머로 근무 중.
'프로그래밍' 카테고리의 다른 글
[펌] Boost 로 C++0x의 라이브러리 「TR1」을 미리 사용 해 보 자 (5) (0) | 2012.08.13 |
---|---|
[펌] Boost 로 C++0x의 라이브러리 「TR1」을 미리 사용 해 보자 (4) (0) | 2012.08.13 |
[펌] Boost 로 C++0x의 라이브러리 「TR1」을 미리 사용 해 보자 (1) (0) | 2012.08.13 |
[펌] Lock-Free Queue (0) | 2012.08.11 |
Proactor pattern (0) | 2012.08.11 |