2012-06-01 85 views
0

我想定義運算符< <以像STL算法一樣工作的方式對元素序列進行操作,方法是將容器的第一個和最後一個元素。與僅採用一個參數相反,容器本身(例如,開發序列的ostream <<運算符

std::ostream& operator<< (std::ostream &out, std::list inList); 

,這樣我就只需要編寫一個函數,如果我使用列表,向量,陣列,等我將不得不調用函數有兩個參數,inList.begin會不管工作( )和inList.end()

的問題是,操作者< <只有一個參數。解決這個問題的最好方法是什麼?

編輯:謝謝你的回答。我應該更清楚地表明,我希望能夠打印一系列元素,包括可能的容器子序列(再次像STL算法一樣)。例如。如果向量v有5個元素,我希望能全部打印出來,像這樣的輸出給從v.begin())的序列v.end(:

[element1 element2 element3 element4 element5] 

但我想我也可以打印前三隻,範圍在[v.begin(),v.begin()+ 3)

[element1 element2 element3] 

請問你的建議答案在這種情況下工作嗎?

回答

2

你不能從一個傳遞參數了,但你想要的東西與任何一種容器的工作。因此,理想情況下你會想要一個像

template <typename T> 
std::ostream& someFunction(std::ostream& out, T first, T last) { 
    // do your stuff 
} 

ostream& operator<<功能尋找東西

template <T> 
std::ostream& << (std::ostream& out, const T& sequence) { 
    return someFunction(out, sequence.begin(), sequence.end()); 
} 

然而,該運營商將與預定義的人發生衝突,所以你不能只是實現它這樣。幸運的是,你可以玩一些模板魔法來解決這個問題,並看到一個非常好的解決方案,檢查出this SO question和相應的github project

注意,因爲(大概)的目標是讓集裝箱通用ostream& operator<<,和你可以通過函數模板來實現這一點,但讓函數使用迭代器並不重要。它也可以使用對容器的(const)引用。

1

通行證只有一個參數,並採取beginend的方法的內部。所有std容器都有beginend。不,您不能將參數的數量更改爲operator <<

+1

1)注意,必須寫一個函數模板,而不是函數。 2)也許'std :: begin()','std :: end()'會更好? –

+0

@Robᵩ1)可能2)不明白爲什麼......它是否支持主編譯器? –

+0

2)因爲'std :: begin()'除了'std ::'容器之外還有專門的數組。 –

1

這是一個老問題,但我必須解決同樣的問題,所以最近想我會在這裏發佈我的解決方案。 Range和makeRange重複了std :: pair和std :: make_pair的功能,但爲了避免衝突(其他類型的對可能以不同的方式打印),我添加了前者。

#include <iostream> 

using namespace std; 

template <typename Iterator> 
struct Range 
{ 
    Range(); 
    Range(Iterator begin_, Iterator end_) : begin(begin_), end(end_) {} 

    Iterator begin, end; 
}; 

template <typename Iterator> 
Range<Iterator> 
makeRange(Iterator begin, Iterator end) 
{ 
    return Range<Iterator>(begin, end); 
} 

template <typename InputIterator> 
ostream & 
operator<<(ostream & out, Range<InputIterator> const & range) 
{ 
    for (InputIterator iter = range.begin; iter != range.end; ++iter) 
    { 
    if (iter != range.begin) out << ", "; // adjust formatting to taste 
    out << *iter; 
    } 

    return out; 
} 

int 
main(int argc, char * argv[]) 
{ 
    int a[] = { 1, 2, 3, 4, 5 }; 
    cout << makeRange(a, a + 2) << endl; // prints 1, 2 
}