[英]Overload operator for both std::vector and std::list
我想使用以下代碼為std::list
和std::vector
重載operator<<
。 但這兩個功能幾乎相同。 有沒有辦法將它們組合起來, 即創建一個更通用的重載?
#include <iterator>
#include <iostream>
#include <vector>
#include <list>
template <typename T>
std::ostream &operator<<(std::ostream &out, const std::vector<T> &v)
{
if (!v.empty())
std::copy(v.begin(), v.end(), std::ostream_iterator<T>(out, ", "));
return out;
}
template <typename T>
std::ostream &operator<<(std::ostream &out, const std::list<T> &v)
{
if (!v.empty())
std::copy(v.begin(), v.end(), std::ostream_iterator<T>(out, ", "));
return out;
}
int main()
{
std::cout << std::vector<int>({1, 2, 3, 4}) << std::endl;
std::cout << std::list<int>({1, 2, 3, 4}) << std::endl;
return 0;
}
template <typename T, typename A, template <typename X, typename Y> class C>
std::ostream &operator<<(std::ostream &os, const C<T,A> &container)
{
if(!container.empty())
std::copy(container.begin(), container.end(), std::ostream_iterator<T>(os, " "));
return os;
}
int main() {
list<int> l{1,2,3,4,5};
vector<string> v{"one","two","three"};
cout<<l<<endl<<v;
return 0;
}
在線演示 。
順便說一句,你可以在這個SO問題中找到使用模板模板的其他例子。
但是你必須小心這種結構:
備注: 如果您尋找通用解決方案,最好考慮創建一個使用迭代器作為參數的適配器模板,然后為此適配器編寫通用提取器。
輸入C ++ 20以及可能包含的概念和范圍 ,您的問題的解決方案可以大大簡化。
概念基本上是具有約束的模板參數,例如
// Taken from https://en.cppreference.com/w/cpp/experimental/constraints
template <typename T>
concept bool Integral = std::is_integral<T>::value;
template <Integral T> // Using concept Integral.
void foo(T i) { /* ... */ } // 'i' has to be integral, or compile time error.
現在, Range (簡化)的概念符合接口(偽代碼):
Range {
begin()
end()
}
使用它,可以編寫如下內容:
template <Range T>
std::ostream& operator<<(std::ostream& out, T&& rng) {
std::copy(std::forward<T>(rng), std::make_ostream_joiner(out, ", "));
return out;
}
它適用於任何有begin()
和end()
,例如
std::cout << std::vector{1, 2, 3, 4, 5} << std::endl; // Ok
std::cout << std::list{1, 2, 3, 4, 5} << std::endl; // Ok
另外,請注意我使用std::make_ostream_joiner
而不是std::ostream_iterator
。 它使用了一個新的C ++ 20迭代器std::ostream_joiner
,它在跳過額外尾隨分隔符的每兩個對象之間寫入分隔符,即你將獲得"1, 2, 3, 4, 5"
而不是"1, 2, 3, 4, 5, "
。
讓我們希望所有這些功能都成為C ++ 20 :)
注意:給出的所有示例都是假設的C ++ 20代碼,目前不使用我所知的任何發布 - 構建編譯器進行編譯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.