この例はSTLコンテナーに関するものなので、それらについて読んでいます。range-for
ループを繰り返し使用してコンテナーのコンテンツを印刷するのは非常に面倒です。そこで、挿入演算子<<
をオーバーロードすることを考えたので、次のように書くことができますstd::cout << container << std::endl;
。
template<class T>
std::ostream& operator<<(std::ostream& out, const std::list<T>& v) {
for (const auto& e : v)
out << e << ", ";
return out;
}
int main() {
std::list<int> vi{ 10, 24, 81, 57, 2019 };
vi.pop_back();
std::cout << vi << std::endl; // 10, 24, 81, 57,
std::deque<std::string> names{ "Hello", "STL Containers" };
std::cout << names << std::endl; // error here. Bacause I've not overloaded << to take a std::deque<T>
}
上で見ることができるように、私list
はあるタイプのを印刷するのがとても快適だと思います。問題は、リストを印刷することはできますが、vector
またはのような他の種類のコンテナを印刷することはできないということdeque
です...
では、どのようにオーバーロード<<
してタイプのコンテナーを取得することができT<U>
ますか、それともすべてのコンテナーに特化する必要がありますか?実際の例では、私はそれをすべきではありませんか?
次のオーバーロードを提供できます。
template <class...>
using void_t = void;
template <class... Args>
constexpr bool exists_t_v(){
return std::is_same<void_t<Args...>, void>::value;
}
template <class Container, class = std::enable_if<
exists_t_v<
decltype(std::begin(std::declval<Container>())),
decltype(std::end(std::declval<Container>()))
>()
>>
std::ostream& operator<<(std::ostream& os, Container&& container){
for(const auto& e : std::forward<Container>(container))
os << e << ',';
return os;
}
これは、任意のインスタンスようになるcontainer
タイプのContainer
ためにstd::begin(container)
と、std::begin(container)
オーバーロードを使用するように定義されています。
このようなソリューションの問題の1つは、std::string
サポートstd::begin()
と、およびstd::end()
が定義されている独自のオーバーロードをすでに提供しているタイプです。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加