2011-09-28 9 views
8

彼の最新の話の1つでは、Herb Sutterは無料のbegin(container)end(container)ファンクションテンプレートをcontainer.begin()よりも好むことを推奨しました。これらの関数は、begin()/ end()メソッドに付属していないすべての反復可能な型に対して提供できるため、好きです。私のドメインクラスのほとんどはドメイン言語で話すインターフェイスを持ち、begin/endのような一般的な名前は使用しないため、STLコンテナと互換性のある反復可能なインターフェイスを提供し、メインクラスインターフェイスを乱すことなくループを範囲指定できます。 自分のタイプのbegin/end関数を提供する最善の方法は何ですか?私の最初の考えは、swapと同じ方法で行い、私の型が存在するのと同じ名前空間に関数を書くことでした。あなた自身のタイプのために無料のbegin/end機能を提供する方法

namespace My 
{ 

class Book 
{ 
public: 
    typedef std::vector<Page>::const_iterator PageIterator; 

    PageIterator FirstPage() const { return begin(pages_); } 
    PageIterator LastPage() const { return end(pages_); } 

private: 
    std::vector<Page> pages_; 
}; 

Book::PageIterator begin(const Book& b) 
{ 
    return b.FirstPage(); 
} 

Book::PageIterator end(const Book& b) 
{ 
    return b.LastPage(); 
} 

} 

ここでADLに頼っても構いませんか、それとも標準的な名前空間にあるべきですか?私は別の方法は、stdの名前空間(stdのオーバーロードは許可されていません、右)の専門化を提供することだと思う。範囲ベースのループの検索に関する、espaciallyの最良の方法は何ですか?

答えて

8

私はADLにその作業を任せます。 std名前空間に特殊化を追加することは許可されていますが、あなたの名前空間に平易な自由関数があれば、そうすることができる理由はありません。ループの範囲に特に

、標準状態:

§6.5.4/ 1(の定義が始まる-exprのエンドexprを):

  • をそれ以外の場合、begin-exprとend-exprはそれぞれbegin(__range)end(__range)で、beginとendは引数依存ルックアップ(3.4.2)で検索されます。この名前検索のために、名前空間stdは関連する名前空間です。
4

これは完全にOKで、ADLに「依存する」ことをお勧めします。 beginend関数は、型のインターフェイスの一部です(関数が自立しているかどうかにかかわらず)、型と同じ名前空間にある必要があります。

関連する問題