표준 템플릿 라이브러리(STL, Standard Template Library)를 사용해야되는이유

C# & MFC
[저자: 김승태 / 유진로보틱스 주임연구원]

표준 템플릿 라이브러리에는 기존의 라이브러리와 달리 몇 가지 큰 장점이 있다. 스택, 리스트, 큐, 균등 트리 등의 데이터 구조에 대한 직관적인 인터페이스를 제공해 사용자가 손쉽게 사용할 수 있다. 또한 정렬, 이진 탐색, 찾기, 병합(Merge), 최대 원소 관리, 상위 n개의 원소 검색 등의 고급 알고리즘도 제공한다. 이런 고급 연산 기능은 기존 라이브러리에서 제공하는 저수준 기능과는 크게 달라진 점이다. 그리고 이 기능은 예외 처리를 기반으로 제공된다. 예를 들어 컨테이너에 저장되어 있는 어떤 원소에 대해 접근하기 위해 사용되는 함수 at은 지정된 매개변수가 접근할 수 있는 범위를 넘어설 경우 예외 out_out_range를 던진다. 이와 같이 많은 에러가 발생하는 상황에 대해 예외를 정의해 놓아 프로그램이 언제나 제어가 가능한 안전한 상태에 놓일 수 있도록 해 주고 있다. 포인터를 이용한 배열형 메모리의 관리에서 매번 직접 인자를 검사해야 하는 것과는 큰 차이가 있다.
표준 템플릿 라이브러리의 가장 큰 매력은 더 이상 포인터를 관리하지 않아도 된다는 데 있다. 고급 컨테이너와 알고리즘, 그리고 이터레이터가 제공하는 프로그래밍 구조는 포인터가 필요한 대부분의 경우를 대체할 수 있도록 해 주고, 더불어 높은 수준의 에러 처리 구조와 지능적인 연산에 의해 포인터를 직접 사용할 때보다 훨씬 더 안전하고, 효율적으로 데이터를 관리할 수 있도록 도와준다.
두 번째로 표준 템플릿 라이브러리는 제네릭 프로그래밍(Generic Programming)을 기반으로 이루어져 있다. 즉, 템플릿을 기반으로 제공되는 클래스와 함수들은 이들 내부에서 사용하고 있는 각 타입들을 많은 경우 템플릿 매개변수화하여 제공하고 있고, 이에 따라 실행 시간에 비용을 지불하지 않는 높은 효율성을 지닌 프로그램의 일반화가 가능하도록 해 준다.
또한, 표준 템플릿 라이브러리는 표준의 일부이기 때문에 g++, 비주얼 C++ 등의 특정한 번역 환경을 가정하지 않아 이를 기반으로 작성된 프로그램이 어느 곳에서나 동일하게 번역되고, 실행되는 것이 보장된다. 즉 작성된 프로그램의 이동성(Portability)이 최대한 보장되는 것이다.
이러한 매력에도 불구하고 많은 C++ 언어 사용자들이 표준 템플릿 라이브러리의 사용을 꺼려하고 있다. 표준 템플릿 라이브러리라고 하면 어려운 전문가의 도구, 혹은 뭔가(?) 특별한 목적으로 사용하는 것으로 생각하는 경우가 많기 때문이다. 하지만 지금까지 말해왔듯 그렇지 않다. 스택, 리스트, 트리 등의 데이터 관리와 정렬, 합병, 제일 큰 원소 찾기 등의 기능은 아주 일반적인 것이다. 많은 프로그램에서 이를 직접 구현해 사용하고 있을 것이다. 표준 템플릿 라이브러리는 바로 이런 일을 대신하는 것을 목적으로 만들어졌다. 대단한 무언가가 절대 아니다. 사용자는 단지 자신이 사용할 컨테이너와 알고리즘을 필요에 따라 선택하고, 사용하기만 하면 되는 것이다.
템플릿(Template)이라는 이름 때문에 쉽게 범접할 수 없는 어려움이 느껴지지만 템플릿의 기본 기술을 사용할 수 있는 정도만 파악한다면 표준 템플릿 라이브러리를 사용하는 것은 그다지 어렵지 않다. 오히려 사실 이제 막 C++ 언어를 배우려는 개발자는 표준 라이브러리를 사용하는 것부터 시작하는 편이 좋다. 표준 라이브러리는 직관성이 높은 라이브러리인 동시에 높은 수준의 연산을 지원해 주기 때문이다. 그래서 C++ 언어 문법의 가장 기초적인 것만 파악하고 있어도 표준 라이브러리를 사용하여 프로그램을 작성하는 데는 전혀 문제가 없다. 오히려 반드시 해야 할 에러 처리 등을 생각하면 이를 직접 수행하는 것보다 표준 라이브러리의 에러처리에 의존하는 것이 훨씬 더 이득이 된다. 그렇기 때문에 많은 전문가들이 표준 라이브러리를 사용하는 것에서부터 C++ 언어를 시작하기를 추천한다.
이 외에도 작업 환경에 대한 지원 때문에 표준 템플릿 라이브러리의 사용을 꺼려하기도 한다. 가장 일반적인 환경이 비주얼 C++, g++ 등일 텐데, 표준 템플릿 라이브러리 자체가 길어야 10여년 전에 탄생되었던 점을 감안하면 이들 환경에서 표준 템플릿 라이브러리를 제대로 지원하기 시작한 것은 그다지 오래된 일이 아니다. 그래서 애써 표준 템플릿 라이브러리를 배워 프로그램에 적용하더라도 번역이 안되거나 거의 암호화된 수준의 에러 메시지를 만나 당황했을 것이다. 하지만 비주얼 C++ 6.0 버전 이상, .NET, g++3.3 버전 등의 비교적 최신 컴파일러에서는 이제 표준 템플릿 라이브러리를 거의 완벽하게 지원하고 있다. 아직 세부 구현에 실수가 있긴 하지만 대다수의 실제적인 적용에 있어 심각한 문제를 초래하는 경우는 거의 없다. 또한 STLFilt 등의 널리 알려진 무료 진단 도구는 복잡한 에러 메시지를 간단한 형태로 바꾸어 에러 메시지의 내용을 쉽게 이해할 수 있는 형태로 바꿔주므로 이런 도구를 적극적으로 이용하는 것도 좋다.
뜻밖에도 개발자 중에는 왜 표준 템플릿 라이브러리를 사용하지 않는가에 대한 대답으로 “MFC를 사용하는데 또 STL을 사용해야 할 이유가 있는가?”라고 반문하는 경우가 많았다. 그런데 이는 표준 템플릿 라이브러리에 대한 잘못된 이해로 생기는 의문이다. 표준 템플릿 라이브러리는 MFC(Microsoft Class Library)와 아무 관계가 없다. 아니, MFC와 표준 템플릿 라이브러리를 함께 사용해야 더 강력한 프로그램을 작성할 수 있다. MFC와 표준 템플릿 라이브러리가 추구하는 목적이 근본부터 다르다. 표준 템플릿 라이브러리는 컨테이너, 알고리즘 등 데이터 구조와 관련된 인터페이스를 플랫폼 독립적인 방법으로 제공하는 것이 주목적이지만, MFC는 GUI(Graphics User Interface)를 윈도우라는 실행 환경에서 쉽게 프로그램화할 수 있도록 하는 것이 주목적이어서 서로 겹치는 부분이 거의 없다. 더구나 이들을 구성하는 패러다임 역시 전자는 명령형, 제네릭, 함수형 패러다임을 섞어 쓴 반면, 후자는 개체지향적이다. 물론 비슷한 목적의 요소가 다소 있기는 하다. 문자열을 관리하는 CString과 표준 라이브러리의 string, 리스트를 구현한 CObList와 표준 라이브러리의 list 등이 그것이다. 하지만 적어도 필자의 경험으로는 표준 라이브러리가 MFC 라이브러리보다 훨씬 나은 방법을 제공하고 있으며, 아마 표준 라이브러리를 사용한다면 여러분도 나와 같은 경험을 하게 될 것이다.
표준 템플릿 라이브러리를 아직 사용하지 않는 C++ 프로그래머라면 지금부터 접해보라고 자신있게 말할 수 있다. 먼저 시퀀스 컨테이너의 일종인 vector를 malloc으로 관리하는 동적 배열을 대체하는 것으로부터 시작해 보라. 전혀 새로운 C++ 세계를 경험할 것이다.
신고
Posted by 녹두장군