2013-10-11 89 views
9

<algorithm>標頭提供了std::equal_range(),以及一些容器將其作爲成員函數。這個函數困擾我的是它返回了一對迭代器,使得從開始迭代器迭代到結束迭代器變得繁瑣。我希望能夠使用std::begin()std::end(),以便我可以使用C++ 11基於範圍的for-loop。現在我可以專注於std :: begin和std :: end以獲得equal_range()的返回值嗎?

,我聽到關於矛盾的信息,以專業std::begin()std::end() - 有人告訴我,添加什麼不確定的行爲std命名空間的結果,而我也被告知,你可以提供自己的專長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

但我想知道,有什麼缺點來這樣做呢?有一個更好的方法嗎?

回答

7

17.6.4.2.1/1 C++程序的行爲,如果其添加聲明或定義除非另有規定到命名空間std或一個命名空間 命名空間std內未定義。只有當聲明依賴於用戶定義的類型並且 專業化符合 原始模板的標準庫要求並且沒有明確禁止時,程序可以將用於任何標準庫模板的 模板專用化添加到名稱空間 std

所以是的,我相信,從技術上講,您的代碼表現出未定義的行爲。也許你可以寫一個簡單的類,它在構造函數中使用一對迭代器,並實現begin()end()方法。然後你可以寫一些像

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

究竟是如何'挑剔'是關於它允許的部分,如果涉及用戶定義的類型?該對包含迭代器,它遍歷unique_ptrs的容器到我的用戶定義類型。 –

+0

您所寫的定義中沒有提及任何用戶定義的類型。這些模板最終可能會用用戶定義的類型實例化,但這不相關。 –

+1

在任何情況下,「取決於用戶定義的類型」轉義孵化只適用於模板專業化。你的不是:它們是主要的函數模板,它恰好會重載具有相同名稱的其他函數模板。 –

相關問題