2013-10-11 12 views
9

<algorithm>ヘッダーは、std::equal_range()と、それをメンバー機能として持ついくつかのコンテナを提供します。この関数で私を悩ますのは、イテレータのペアを返すことです。イテレータを開始してからイテレータを繰り返すのは面倒です。 std::begin()std::end()を使用して、C++ 11レンジベースのforループを使用できるようにしたいと考えています。私は未定義の動作でstd名前空間の結果には何も追加することを言われてきた、私はまた、あなた自身の専門分野を提供することができることが言われているのに対し、 - 今、私はstd::begin()std::end()を専門に関しては矛盾した情報を聞いたequal_range()の戻り値にstd :: beginとstd :: endを特化できますか?

std::begin()およびstd::end()である。

これは私が今やっているものです:

namespace std 
{ 
    template<typename Iter, typename = typename iterator_traits<Iter>::iterator_category> 
    Iter begin(pair<Iter, Iter> const &p) 
    { 
     return p.first; 
    } 
    template<typename Iter, typename = typename iterator_traits<Iter>::iterator_category> 
    Iter end(pair<Iter, Iter> const &p) 
    { 
     return p.second; 
    } 
} 

そして、これが作業を行います。http://ideone.com/wHVfkh

しかし、私は疑問に思って、これを行うに欠点は何ですか?これを行うより良い方法はありますか?それは、特に断らない限り、名前空間stdstdまたは名前空間 にする名前空間に宣言または定義を追加した場合、C++プログラムの

答えて

7

17.6.4.2.1/1動作は未定義です。プログラムで 標準ライブラリテンプレートのテンプレート特殊化を名前空間 stdに追加する場合は、宣言がユーザー定義型に依存し、 特殊化が オリジナルテンプレートの標準ライブラリ要件を満たし、明示的に禁止されていない場合のみです。

はい、私は、技術的には、あなたのコードは未定義の動作を示すと信じています。おそらく、コンストラクタでイテレータのペアをとり、begin()end()のメソッドを実装する単純なクラスを書くことができます。

for (const auto& elem: as_range(equal_range(...))) {} 
+0

ユーザー定義型が関与している場合、「picky」はどのように許可されるのですか?このペアには、unique_ptrsのコンテナをユーザ定義型に反復するイテレータが含まれています。 –

+0

あなたの定義は、書かれているように、ユーザ定義の型は言及していません。これらのテンプレートは最終的にユーザー定義型でインスタンス化されるかもしれませんが、それは無関係です。 –

+1

いずれの場合でも、「ユーザー定義型に依存する」エスケープハッチは、テンプレートの特殊化にのみ適用されます。あなたはそうではありません。それらは主要な関数テンプレートです。同じ名前の他の関数テンプレートに過度の負荷がかかります。 –

関連する問題