프로그래밍 언어2017.09.14 10:11

오래전에 JAVA의 DataInputStream, DataOutputStream을 이용해 object serialization 비스무레한걸 구현 했었다.

그 때는 Android에서 동작하기만 하면 되었기 때문에, 아무 생각없이 구현을 했었는데,

오랜 시간이 지나 C++에서 그 때 저장되었던 파일을 읽으려고 하니, 간단한 문제가 아니더라. ㅠㅠ


암튼, 그래서 C++로 DataInputStream 비스무레하게 구현을 해 보려고 했는데, 기본타입에 대해서는 문제가 없는데,

문자열이나 특수한 타입에 대해서는 별도로 구현을 해 주어야 했다.

함수 인터페이스를 동일하게 만들기 위해서 function template으로 구현을 하는데,

이게 function template은 partial specialization이 불가능 하기 때문에 함수 인터페이스가 예쁘게(?) 나오지 않았다.

고민하다가, 오랜만에 Effective C++을 다시 꺼내서 훑다 보니, 역시 힌트가 있었다. Thanks Scott!




함수 반환을 성공/실패로 하고, 결과를 참조로 반환하면 타입 추론이 되니,

template argument를 명시적으로 안 줘도 될텐데... 디자인의 문제이니, 좀더 고민 해 보자.

Posted by 가리봉 개발자(?) 세월의돌
프로그래밍 언어2016.08.25 15:46

뭔가 복잡하고 완벽하게 만들려면 좀더 까다롭겠지만,

range-based for loop 또는 std:find 등의 STL algorithm을 이용할 수 있도록 간단하게 만든다면, 아래와 같이 하면 되겠다.

(물론 검증된 것은 아니고, 정말 연습용으로 해 보고 정리하는 것임. 따라서 오류가 있을수도...;;)




template <typename T> class slist는 이미 정의가 되어 있고,

template <typename T> class slist_iterator가 friend로 지정되어 있다.

(또는 slist의 nested class로 구현하여도 되겠다)


처음에는 아래와 같은 type을 노출하지 않았었다.


그 상태로 range-based for loop은 문제가 없었지만, std::find를 호출 했더니, iterator_category를 지정해야 한다는 에러 메시지가 나와서 추가 해 주었다.


그랬더니 std::iterator_traits 뭐라뭐라 에러가 나는데, 뭐라 하는지 전혀 모르겠더라;;


그래서 혹시나 하는 마음에 value_type, reference를 추가 해 보았으나 동일ㅠㅠ


결국, stackoverflow에서 해답을 찾았다. (오늘 알게 된 사실인데, 해당 글의 const_iterator 구현 부분에서 operator*, operator->의 반환값이 그냥 reference, pointer로 되어 있어, 값을 할당하여도 에러가 발생하지 않는다. 이 부분은 수정이 필요함. 맨 아래 전체 소스 참고.)


위의 네 개의 타입과 iterator_category는 반드시 노출되어야 하고,

iterator_category에 따라 필요한 멤버함수들을 구현 해 주면 된다.


정말 간단하게 구현하는 방법은 std::iterator를 상속하여 구현하는 것인데,

이놈이 C++17에서 없어질 예정이므로, 이후 어떻게 해야 할지는 알아봐야 할듯.


아래는, 허접하지만 const_iterator까지 구현한 전체 소스 (__)

Posted by 가리봉 개발자(?) 세월의돌

티스토리 툴바