我已经有了这个有效的代码:
template <typename T1, typename T2>
std::ostream& operator<<(std::ostream &out, std::map<T1, T2> &map){
for (auto it = map.begin(); it != map.end(); ++it) {
out << it-> first << ", " << it->second << '\n';
}
return out;
}
template <typename T1, typename T2>
std::ostream& operator<<(std::ostream &out, std::unordered_map<T1, T2> &map){
for (auto it = map.begin(); it != map.end(); ++it) {
out << it-> first << ", " << it->second << '\n';
}
return out;
}
正如您所看到的,两个功能几乎完全相同。有没有办法删除一个并只使用一个抽象函数?
答案 0 :(得分:3)
您确实可以:这里是任何可迭代类型的单一函数模板,其value_type
为std::pair<>
。这不仅适用于std::map<>
和std::unordered_map<>
,还适用于std::vector<std::pair<>>
,boost::container::list<std::pair<>>
等:
namespace detail {
template<typename>
struct is_pair : std::false_type { };
template<typename T1, typename T2>
struct is_pair<std::pair<T1, T2>> : std::true_type { };
}
template<
// collection type
typename T,
// ensure value_type exists
typename VT = typename T::value_type,
// ensure value_type is some std::pair<>
typename std::enable_if<detail::is_pair<VT>{}>::type* = nullptr
>
auto operator <<(std::ostream& out, T const& coll)
// ensure begin(coll) and end(coll) are legal
-> decltype(void(begin(coll)), void(end(coll)), out) {
for (auto it = begin(coll); it != end(coll); ++it) {
out << it->first << ", " << it->second << '\n';
}
return out;
}
答案 1 :(得分:0)
这是一个示范程序
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>spring-boot-fundamentals</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.1.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.7</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-legacy</artifactId>
<version>1.0.2.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<packaging>war</packaging>
</project>
它的输出是
#include <iostream>
#include <map>
#include <type_traits>
#include <utility>
template <class T1, class T2, class T3, class T4,
template <class T1, class T2, class T3, class T4> class Container>
std::ostream & operator<<( std::ostream &out, const Container<T1, T2, T3, T4> &c )
{
static_assert( ( std::is_same<typename Container<T1, T2, T3, T4>::value_type,
std::pair<const T1, T2>>::value ), "Invalid value type of the Container" );
for ( const auto &p : c )
{
out << p.first << ", " << p.second << '\n';
}
return out;
}
int main()
{
std::map<int, char> m =
{
{ 65, 'A' }, { 66, 'B' }, { 67, 'C' }
};
std::cout << m << std::endl;
std::multimap<int, char> mm =
{
{ 65, 'A' }, { 66, 'B' }, { 67, 'C' }
};
std::cout << mm << std::endl;
return 0;
}