C++, template 초보질문 드립니다. 조언 좀 부탁드려요...
글쓴이: tien770 / 작성시간: 목, 2012/11/01 - 9:53오후
여러가지 형태의 데이터를 저장하려고 이런 클래스를 사용하고 있습니다.
질문에 필요한 부분만으로 단순화시켰습니다.
class MyData { public: void Push(int data) { IntData.push_back(data); } void Push(float data) { FloatData.push_back(data); } void Push(string data) { StringData.push_back(data); } vector<int> IntData; vector<float> FloatData; vector<string> StringData; };
그런데 필요한 type마다 다 저렇게 만들어주는건 비효율적인것 같아서 template을 쓰려고 시도하였습니다.
class MyData2 { public: // 1. 이렇게 만들고 싶었는데, XXX부분을 어떻게 써야 할지 모르겠습니다. template<typename T> void Push1(T data) { XXX.push_back(data); } // 2. 그래서 이렇게 시도를 해 보았는데, 컴파일러가 메시지박스 보이고 죽어버립니다 ㅠㅠ template<typename T> void Push2(T data) { Data<T>.push_back(data); } template<typename T> vector<T> Data; // 3. 결국 이 방법으로 성공은 했습니다만... template<typename T> void Push3(T data) { Container<T>().push_back(data); } template<typename T> vector<T> &Container(void) { static vector<T> v; return v; } // 4. 모든 data를 다 뒤지려면 비슷한 문제가 다시 발생합니다. 게다가, 빼먹는 data가 분명 생길테구요. void Save2File() { Save(Container<int>()); Save(Container<float>()); Save(Container<string>()); } template<typename T> void Save(const vector<T> &c) const { c; } };
결국 대안은 없는 것일까요.
저것 때문에 덩치큰 데이터관리 모듈을 만들기는 배꼽이 더 큰거 같고
분명 명쾌하고 간단한 실마리가 있을거 같은데... 감을 못 잡겠네요.
조언 좀 부탁드립니다.
Forums:
템플릿 함수 대신 아래처럼 템플릿 클래스를 사용하시면
템플릿 함수 대신 아래처럼 템플릿 클래스를 사용하시면 됩니다.
template
class MyData
{
void Push(T data) { Storage.push_back( data ); }
vector Storage;
};
4번 문제는 마찬가지 아닌가요?
함수가 템플릿이든 클래스가 템플릿이든 마찬가지 아닌가요?
여기저기에서 Push를 사용할 경우에, 나중에 모든 데이터를 다 찾아내려면
사용된 모든 타입들을 다 기억하지 않는한
일부 데이터를 빠트리게 되는 상황이 말이죠.
답변 주신 내용은 2번 항목까지에 해당하는 것 같은데요.
그냥 클래스 사용해보시는건 어떠실지?
아이템 부분을 구현하시려는 것이 아닐까 싶은데요.
아이템이라는 클래스를 만들어 모든 아이템에서 필요한 부분을 최상위 클래스에서 구현해놓는거죠.
음. 질문이 그러니까..
템플릿을 사용해서 사용자가 명시적으로 클래스를 인스턴스화 할 때 쓰겠다는 것이 아니라.
예) MyClass 이런것 없이..
코드상에서 사용자 마음데로 아무 자료형이나 push를 하고 컴파일러가 알아서 그것들을 종합해서 "이 클래스는 이러한 자료형들을 필요로 해"
라고 하고 싶으신거죠? - 그렇다면 쉽지 않아보입니다만..
어차피 기존의 프로그래밍 방법 자체가 각 필요한 자료형에 대한 vector를 클래스에 일일이 선언하시는 거라면
그러면 선언하실때 MyClass<필요한 타입들..> 만 하시면 원하시는 기능을 구현하실 수는 있습니다.
다만 C++11 에서 제공하는 Variadic Template이 필요하죠.
만약 C++11이 불가능하시다면 아쉬운데로 tuple을 이용해서 어느정도 흉내는 낼 수 있습니다만 이 또한
템플릿 갯수별로 setter와 getter를 또 만들어주셔야 합니다. (좀 많이 길어집니다만 하나 만들어두면 두고두고 사용하실 수는 있겠지요.)
예제코드입니다.
참고하시면 될 듯 합니다.
출처는
출처 기입을 깜빡했네요. 연구실에 학부 연구생이 있는데 그친구가 짰습니다. https://github.com/Mortal/varvector
감사합니다.
코드를 딱 보기만 해도, 공부하기 참 좋다는 생각이 듭니다.
최근에서야 boost를 설치했기에, 아직 boost::enable_if 같은거에 익숙하지는 않지만
바로 감이 잡히네요.
처음에 컨테이너를 만들때에 미리 예상 타입들을 다 열거해 놓아야 한다는거 말고는 정말 만능이라고 여겨집니다.
요즘 공부하고 있는 Typelist가 딱 떠오르네요.
좋은 공부되게 해 주셔서 감사합니다.
그냥 클래스로 만드시는 것도 괜찮겠다 해서.
Objective-C의 Foundation 프레임워크에 있는 NSMutableArray에서 영감을 얻어
C++ 스타일로 새롭게 작성해봤습니다.
만들어놓은 파일이 많아 압축 파일로 올려볼게요.
아직 구현이 덜 된 부분도 있지만 제법 괜찮게 동작하는 것 같군요.
최상위 객체가 있으면 이렇게 편리하게 다룰 수 있습니다..는 정도만 보시면 될 것 같습니다.
저는 이렇게 생각했습니다.
올려주신 소스 잘 보았습니다.
템플릿이 아니라 클래스 계승을 통해 구성하셨네요.
방향전환이 참신하다고 생각했습니다.
다만 현재 올려주신 소스로는 addObject한 객체가 스코프 벗어나서 소멸되면
문제가 발생하는 구조이기 때문에 그 부분만 조금 손보면
훌륭한 방법이 될 수 있을거라 생각됩니다.
그리고 HDObject 객체를 미리 만들어서 넣는 것보다는
addObject를 템플릿 함수로 만들고,
거기에서 변환을 해서 집어넣어주는게 사용상에는 편리할 듯 싶습니다.
좋은 아이디어 주셔서 감사합니다.
댓글 달기