2013-11-29 76 views
0

我正在做一個簡單的結構,它包含兩個迭代器,我可以使用基於範圍的循環。模板函數不同的結果取決於引用類型

#include <vector> 
#include <iostream> 
#include <utility> 

template <class TIterator> 
struct Range 
{ 
Range(const TIterator &begin, const TIterator &end) 
    :_begin(begin), _end(end) {} 

TIterator begin() { return _begin; } 
TIterator end() { return _end; } 

private: 
TIterator _begin; 
TIterator _end; 
}; 

template <class TRange> 
auto make_range(TRange r) -> Range<decltype(std::begin(r))> 
{ 
    return { std::begin(r), std::end(r) }; 
} 

template <class TRange> 
auto make_range2(TRange &r) -> Range<decltype(std::begin(r))> 
{ 
    return { std::begin(r), std::end(r) }; 
} 


int main() 
{ 
    std::vector<int> vec = {1,2,3,4,5}; 
    auto r = make_range(vec); 

    for (auto i : r) 
    { 
     std::cout << i << std::endl; // 0 0 3 4 5 or 0 2 3 4 5 depends on compiler 
    } 

    std::vector<int> vec2 = {1,2,3,4,5}; 
    auto r2 = make_range2(vec2); 

    for (auto i : r2) 
    { 
     std::cout << i << std::endl; // 1 2 3 4 5 
    } 

    return 0; 
} 

第一個循環打印出0 0 3 4 50 2 3 4 5(意外)和第二環打印1 2 3 4 5(預期)

有人能向我解釋爲什麼make_range沒有給出正確的價值?以及它如何生產0 0 3 4 50 2 3 4 5?我是否使用過任何未定義的行爲,或者這是編譯器錯誤?

活生生的實例:ColiruIdeone

回答

2

make_range按值取其參數。 r是一個臨時函數,當函數返回時會被銷燬,使所有迭代器無效。隨後的解引用所述迭代器的嘗試展現出未定義的行爲。

1

在make_range(TRANGE R),r是載體,其超出範圍,無效的迭代的本地副本。

相關問題