您如何编写一个库,当它包含在内时,它会使任何* 现有STL容器的<<
运算符超载?
一个自我强加的要求是不得包含任何容器的头文件。这将不必要地膨胀最终的可执行文件。在我希望使用的容器之后包含此标头更有意义。此限制意味着使用templates
或macros
。
我正在寻找建议和指示,所以,请,不要只发布能够做到这一点的完全正常工作的代码!自己实现这一点是学习过程的一部分。代码片段的小片段可以证明某些事情是如何运作的。
到目前为止我做了什么:
我为每个具有不同模板签名的容器重载了<<
运算符。我使用这种方法遇到的问题是,有些容器具有相同数量的模板参数,但有些包含std::pair
- s,其他包含single values
。更准确地说,这是std::map
&amp;的情况。 std::multimap
vs std::unordered_set
&amp; std::unordered_multiset
。
此次碰撞迫使我要么实现其中一个对的非模板版本,要么想出一种区分std::pair
- s和single values
的方法。不过,我真的不知道如何去做第二个。我之所以不直接“如何做到”的原因是我开始相信这可以通过更好的整体设计来完全避免。
提前谢谢你!
什么对我有用:
operator<<
std::pair
operator<<
注意:
template <typename T1>
和template <typename T1, typename T2>
不同template <typename T1, typename T2>
和template <typename T1, size_t T2>
是 不同- 醇>
template <typename T1, typename T2>
和template <typename C1, typename C2>
是不不同
使用“模板中的模板”,例如,函数看起来像:
template <typename Type, template <typename TYPE> class TClass>
void func(TClass<Type>& tc) {
if (tc.somethingTrue())
tc.doStuff();
}
答案 0 :(得分:5)
您可以将operator<<
重载为带有模板模板参数的模板(即任何容器)。
然后你可以提供一个模板函数的两个重载(例如,print
),一个重载将专门用于std::pair
。
template<typename T>
std::ostream& print(std::ostream &out, T const &val) {
return (out << val << " ");
}
template<typename T1, typename T2>
std::ostream& print(std::ostream &out, std::pair<T1, T2> const &val) {
return (out << "{" << val.first << " " << val.second << "} ");
}
template<template<typename, typename...> class TT, typename... Args>
std::ostream& operator<<(std::ostream &out, TT<Args...> const &cont) {
for(auto&& elem : cont) print(out, elem);
return out;
}
答案 1 :(得分:4)
非常这个问题的简单尝试就像:
template<typename T>
void print_container(std::ostream& os, const T& container, const std::string& delimiter)
{
std::copy(std::begin(container),
std::end(container),
std::ostream_iterator<typename T::value_type>(os, delimiter.c_str()));
}