2017-08-31 97 views
1

我試圖獲得關於iterator_traits的更好的知識,並在C++教科書上找到了一小段代碼。所以我添加了一些代碼來使其可執行,目的是理解所述編譯時機制的行爲。完整的程序看起來像這樣:爲什麼decltype()指向引用的指針?

template<typename C> 
    using Iterator_type = typename C::iterator; 

template<typename Iter> 
    using Iterator_category = typename std::iterator_traits<Iter>::iterator_category; 

template<typename Ran>           
void sort_helper(Ran beg, Ran end, std::random_access_iterator_tag) 
{ 
    sort(beg, end); 
} 

template<typename For>          
void sort_helper(For beg, For end, std::forward_iterator_tag) 
{ 
    std::vector<decltype(*beg)> v {beg, end}; 
    sort(v.begin(), v.end()); 
    copy(v.begin(), v.end(), beg);    
} 

template<typename C> 
void sort(C& c) 
{ 
    using Iter = Iterator_type<C>; 
    sort_helper(c.begin(), c.end(), Iterator_category<Iter>{}); 
} 

void test(std::vector<std::string>& v, std::forward_list<int>& lst) 
{ 
    sort(v);  
    sort(lst); 
} 

template<typename C> 
void print(C& c) 
{ 
    for(auto it = c.begin(); it != c.end(); ++it) { 
     std::cout << *it << '\n'; 
    } 
    std::cout << '\n'; 
} 

int main() 
{ 
    std::vector<std::string> v { "Bicycle", "Hoovercraft", "Rocket", "Airplaine", "Bus", "Submarine" }; 
    print(v); 

    sort(v); 
    print(v); 

    std::forward_list<int> lst { 2, 81, 3, 0, 4, 34, 23, 11 }; 
    print(lst); 

    sort(lst); 
    print(lst); 

    return 0; 
} 

編譯失敗,告訴引用指針給出:

memory:1723:16: error: 
    'pointer' declared as a pointer to a reference of type 'int &' 
typedef _Tp*    pointer; 

和錯誤堆棧帶來以下行:

in instantiation of template class 'std::__1::vector<int &,  std::__1::allocator<int &> >' 
    requested here 
std::vector<decltype(*beg)> v {beg, end}; 

此編譯或者在Mac OSLinux機器與g ++

我設法它的工作改進,像這樣涉及的部分:

auto i = *beg; 
std::vector<decltype(i)> v {beg, end}; 

能否請您給我爲什麼decltype()函數返回一個指針引用更清楚的解釋?我讀過關於SO上的decltype類型函數的其他一些問題,並且已經閱讀了規範,但都沒有讓我走上正確的道路,也沒有檢查完整的編譯器輸出消息堆棧是否有幫助。

預先感謝您的任何考慮。

+2

'decltype'產生一個參考,但是真正的錯誤是,你正在試圖建立一個引用'std :: vector '的向量,最終導致指向引用的指針出現。 – VTT

+0

@VTT,是的很清楚。不太明顯的是,如果這是本書作者(Bjarne Stroustrup)的錯誤還是我錯過了其他東西? – wiredolphin

+1

如果這是本書中的內容,它會假設迭代器的偏好類型的性質不成立。請參閱下面的@LogicStuff的答案。 – dhke

回答

2

問題是,decltype產生一個引用類型(你不能使std::vector)。
爲什麼這樣回答here深入。

您可以通過以下兩種方式解決這個問題:

  • 使用std::remove_reference<decltype(*beg)>::type
  • 使用std::iterator_traits<For>::value_type
+1

這兩個'std :: vector :: type> v {beg,end};'和'std :: vector :: value_type> v {beg,end};'給出一個更好的解釋。 – wiredolphin

相關問題