2010-06-10 63 views
15

這是很容易給定的容器,以獲得相關的迭代器,例如容器類型:獲取從在C(其)迭代器類型++(STL)

std::vector<double>::iterator i; //An iterator to a std::vector<double> 

我想知道如果它是可能的,給定的迭代器類型,推導出「相應容器」的類型(這裏我假設每個容器都有一個且只有一個(非const)迭代器)。

更精確地,我想一個,使得模板元函數,它與所有STL容器的工作原理(無需手動專門它爲每個單個容器),例如:

ContainerOf< std::vector<double>::iterator >::type 

評估爲

std::vector<double> 

可能嗎? 如果不是,爲什麼?

非常感謝您的幫助!

+2

你想了解一個Iterator的概念問題?即如果它是隨機訪問? STL爲此使用標籤。通常沒有理由知道迭代器來自哪裏。 – pmr 2010-06-10 18:03:01

+0

你知道最前面你是否有迭代器進入7個STL容器之一,還是你還需要一個「else」子句? – MSalters 2010-06-11 12:56:28

回答

7

我不認爲這是可能的。在一些STL庫中,實際上有一個向量迭代器作爲指針類型,所以我想不出任何可以從中取回容器類型的方法。

+0

但是,這不能是任何其他STL容器的迭代器。只有7個,你可以統統所有人。 – MSalters 2010-06-11 12:55:07

+0

這是一個公平點。那麼map和multimap之間的區別呢?你能告訴他們除了比較運算符嗎? – Hitobat 2010-06-11 15:31:27

+0

如果'std :: iterator_traits '具有'typedef T container_type;'但是你可以用這樣的typedef創建你自己的'std :: iterator_traits_pro',這可能是可能的。 – k06a 2011-12-05 07:41:22

0

C++ STL迭代器的確切運行時類型有意未定義,因此也是特定於實現的。您可以搜索您的編譯器供應商的頭文件以找出實際使用的類型,並從中推導出容器,但它是供應商和版本特定的,因此容易中斷。

+0

感謝您的回覆!我現在很擔心我的問題是故意不能「解決」的。 – stepelu 2010-06-11 08:32:19

0

迭代器的意義在於,您可以在不必知道基礎容器類型的情況下使用它們進行工作,例如傳遞開始/結束對並在該範圍內進行工作。然而,如果你關心的只是迭代器類型,我相信你可以使用迭代器特徵來確定例如迭代器是否是隨機訪問。取std::advance,一般情況是它在迭代器上調用operator++ n次,但專用於隨機訪問迭代器使用+ =代替。

除此之外,我不知道有任何方式從迭代器獲取容器類型。

+0

這是通過標籤調度完成的。 http://www.boost.org/community/generic_programming.html#tag_dispatching – 2010-06-10 18:20:24

5

只是爲了好玩,這裏的東西我迅速用Boost.MPL砍死(警告:這是veeeery表面上測試,所以小心輕放):

#include <boost/mpl/list.hpp> 
#include <boost/mpl/find_if.hpp> 
#include <boost/type_traits.hpp> 
#include <vector> 
#include <string> 
#include <list> 
#include <set> 

// List of candidate container types 
template<typename T> 
struct ContainersOf : boost::mpl::list< 
    std::vector<T>, 
    std::basic_string<T>, 
    std::list<T>, 
    std::set<T> 
>{}; 

// Metafunction to evaluate if IteratorT == ContainerT::iterator 
template<class IteratorT, class ContainerT> 
struct IsIteratorOf 
{ 
    typedef typename 
    boost::is_same< 
     IteratorT, 
     typename ContainerT::iterator 
    >::type type; 
}; 

// Metafunction to compute a container type from an iterator type 
template<class IteratorT> 
struct ContainerOf 
{ 
    typedef typename 
    boost::mpl::deref<typename 
     boost::mpl::find_if< 
      ContainersOf<typename std::iterator_traits<IteratorT>::value_type>, 
      IsIteratorOf<IteratorT, boost::mpl::_1> 
     >::type 
    >::type type; 
}; 

// Test 
int main() 
{ 
    ContainerOf<std::list<int>::iterator>::type l; 
    std::list<int> l2 = l; // OK 
    std::vector<int> v = l; // Fails to compile 

    return 0; 
} 
+0

非常感謝您的回覆,但是您的解決方案需要對容器類型「專業化」,請參閱ContainerOf。 – stepelu 2010-06-11 08:31:48