Skip to main content

C++ of the Day #16 - Question about STL iterator usage

역시 뉴스 그룹에서 하나 가져왔습니다. ((c.l.c.m:Question about STL iterator usage))
오늘 내용은 기술적이라기보단 역사적인 것이네요. :-)

Question

질문은.
  1. iterator를 사용할때 대부분의 사람들은 아래 코드의 1)번보다는 2)번과 같은 방식으로 사용하는 것 같아 보입니다. 이것은 단지 취향 문제인가요 아니면 뭔가 그럴듯한 이유가 있나요?
    i->func(); // 1)
    (*i).func(); // 2)
    


Answer

처음 질문을 보고 저는 "이거야 뭐 그냥 취향 문제 아냐?" 라고 생각했습니다만 P.J. Plauger 씨가 역사적인 이유를 들어 설명을 해주셨네요.

예전에는 컴파일러가 template class를 instantiation할 때 어떤 member function이 실제 호출되는지 여부에 관계없이 모든 member function을 instantiation 할 수 있었다고 합니다. ((아마도 1998년의 표준화보다도 훨씬 이전인듯 합니다.)) 따라서 특정 iterator 클래스를 정의할 때 operator->() 를 정의하는 것은 안전하지 않았습니다. 다음 코드를 보면 이해가 쉬울 것 같습니다.
template <class T>
class Iterator
{
public:
  T& operator*() { // for int - *i
    return *data_;
  }
  T* operator->() { // for int - i-> what?
    return data_;
  }
private:
  T* data_;
};
위의 Iterator 클래스가 만약 어떤 class 타입에 대해 instantiation 되었다면 두 operator 모두 문제 없이 instantiation될 수 있습니다. 왜냐하면 두 문법 모두 그 class의 member 에 접근하기 위해 사용되는 문법이기 때문입니다.

하지만 위의 클래스가 int 와 같은 scalar 타입에 대해 instantiation 된다면 operator->() 은 문제가 됩니다. 왜냐하면 operator*() 은 해당 int 값에 접근하기 위해 *i 와 같이 사용될 수 있지만 operator->()는 대상 멤버가 없이는 사용될 수 없는 operator이고 int 타입은 당연하게도 멤버를 가지고 있지 않기 때문이죠.

따라서 해당 클래스가 instantiation될때 모든 member function들을 instantiation하는 컴파일러들에서 iterator가 동작하도록 하기 위해서는 operator*()은 가질 수 있었지만 opertor->()는 가질 수 없었습니다.

물론 이런 내용은 현재는 맞지 않습니다. 표준 C++에서는 사용하지 않는 member function은 instantiation하지 않는다고 명시하고 있기 때문입니다.

하지만 위에서 설명한 역사적인 이유로 모든 Iterator에서 제공하는 (*i).func() 문법이 i->func() 문법보다 많이 쓰이고 있다고 합니다. ((사실 전 이런 이유는 모른 채 (*i).func() 문법을 선호해 왔습니다. 아마 이쪽이 여러 책이나 글에서 봐오던 것이라 더 눈에 익어서였기 때문인듯 하네요.))

Comments

  1. 전 그냥 i->func()를 쓰는 경우가 많은 듯. 코드상에서 어떤게 더 이쁘고 명확하게 보이느냐에 따라 조금씩 다르기는 하지만요.
    그러고보니 boost::bind때문에 iterator를 갖고 바로 호출해본적이... ( ..)

    그런데 footnote는 어찌 쓰는 건가요?? :)

    ReplyDelete
  2. Footnote 관련해서는 WP-Dokuwiki라는 plugin을 사용하고 있습니다. Dokuwiki라고 꽤나 맘에 드는 문법을 가지고 있는 wiki 엔진인데 이 엔진을 거의 그대로 들어다가 WP용으로 만들어 놓은 plugin이 있어서 가져왔지요. :-)
    Footnote외에도 dokuwiki의 문법을 모두 사용할 수 있어 글 작성하는데 매우 유용합니다. 단점이라면 페이지 로딩 속도가 좀 느려진다는... oTL

    주소는 http://floatingsun.net/blog/code/wp-dokuwiki/ 입니다~

    ReplyDelete
  3. 아. dokuwiki플러긴인군요. 저도 회사에서 dokuwiki를 쓰는지라. ㅎㅎ
    ㄳ-

    ReplyDelete

Post a Comment

Popular posts from this blog

CodeHighlighter plugin test page.

This post is for testing CodeHighlighter plugin which uses GeSHi as a fontifier engine. ((Those code blocks are acquired from Google Code Search .)) ((For more supported languages, go CodeHighlighter plugin or GeSHi homepage.)) C++ (<pre lang="cpp" lineno="1">) class nsScannerBufferList { public: /** * Buffer objects are directly followed by a data segment. The start * of the data segment is determined by increment the |this| pointer * by 1 unit. */ class Buffer : public PRCList { public: Buffer() { ++index_; } PHP (<pre lang="php" lineno="4">) for ($i = 0; $i $value = ord( $utf8_string[ $i ] ); if ( $value < 128 ) { // ASCII $unicode .= chr($value); } else { if ( count( $values ) == 0 ) { $num_octets = ( $value } $values[] = $value; Lisp (<pre lang="lisp">) ;;; Assignment (define-caller-pattern setq ((:star var fo...

C++ of the Day #43 - SQLite3 C++ wrapper #1

The Definitive Guide to SQLite 를 읽다가 공부 겸 해서 C++ wrapper를 만들어 보았습니다. 최대한 C++ 냄새(?)가 나도록 만들어 보았습니다. :-) ((SQLite는 복잡한 관리가 필요없이 사용가능한, 파일이나 메모리 기반의, 라이브러리로 제공되는, 약 250kb 용량의, 대부분의 SQL92문을 지원하는, open source RDB입니다.)) 이 wrapper를 사용하기 위해서는 (당연하게도!) sqlite3 와 (당연하게도?) boost 라이브러리가 필요합니다. 사용 예들을 살펴보는 것으로 설명을 대신합니다. 이번 글에서는 다음과 같은 contacts 테이블이 test.db에 존재한다고 가정합니다. CREATE TABLE contacts ( id INTEGER PRIMARY KEY, name TEXT NOT NULL, phone TEXT NOT NULL, UNIQUE(name, phone) ); Command 먼저 test.db 파일을 사용하기 위해 다음과 같이 파일 이름을 주어 connection 객체를 생성합니다. 생성과 동시에 test.db와 연결이 이루어집니다. ((생성자외에 open() 함수를 사용할 수도 있습니다.)) sqlite3pp::connection conn("test.db"); 다음은 contacts 테이블에 정보를 추가하는 가장 간단한 방법입니다. connection 클래스에서 제공하는 execute 함수를 사용합니다. ((executef 함수를 사용하면 printf와 같은 문법을 사용하여 query문을 작성할 수 있습니다.)) conn.execute("INSERT INTO contacts (name, phone) VALUES ('user', '1234')"); 위와 동일한 작업을 parameterized query를 사용하여 할 수도 있습니다. ((step()함수가 실제 query문을 수행하는 함수입니다. ...

Textiler plugin test page

This post is for testing Textiler plugin . This plugin uses Textile engine (version 2.0.0). The sample text is come from Textile test page. (Note that the result will be vary according to your CSS options.) Supported wiki syntax Rendering result h2{color:green}. This is a title h3. This is a subhead p{color:red}. This is some text of dubious character. Isn't the use of "quotes" just lazy writing -- and theft of 'intellectual property' besides? I think the time has come to see a block quote. bq[fr]. This is a block quote. I'll admit it's not the most exciting block quote ever devised. Simple list: #{color:blue} one # two # three Multi-level list: # one ## aye ## bee ## see # two ## x ## y # three Mixed list: * Point one * Point two ## Step 1 ## Step 2 ## Step 3 * Point three ** Sub point 1 ** Sub point 2 Well, that went well. How about we insert an <a href="/" title="watch out">old-fashioned hypertext link</a>? Will the quo...