1. 程式人生 > 其它 >c++方便的輸出vector和map_過載的應用 【python一樣寫c++、二】

c++方便的輸出vector和map_過載的應用 【python一樣寫c++、二】

寫程式,尤其是除錯的時候,會想著直接輸出一個map或者vector來調錯。

但本來的cout<<沒有這種功能。我們就會想了,要是c++能和python一樣,直接輸出一個列表(vector)或者dict(map),那有多好。

翻翻書可以知道,cout<<的<<也是重載出來的,那我們就再過載一下,來實現自己的功能唄。

老樣子,先放成品

#include<bits/stdc++.h>
using namespace std;

template<typename T>//模板的使用
ostream& operator<<(ostream &o,vector<T> &x){
    string ch="";
    if(typeid(T)==typeid(string)) ch='\"';//特判string型別,用來加入“”
    if(typeid(T)==typeid(char)) ch='\'';
    o<<"[";
    for(int i=0;i<x.size();++i){//可以直接for(auto i:x),但是我不知道怎麼特判第一個來控制","
        o<<((i==0)?"":", ") <<ch<<x[i]<<ch;
    }
    o<<"]"<<endl;
    return o;
}

template<typename T1,typename T2>
ostream& operator<<(ostream &o,map<T1,T2> &x){
	#define geshi(x,ch) if(typeid(x)==typeid(string)) ch='\"';\
	if(typeid(x)==typeid(char)) ch='\''  
	//特判string型別,用來加入“,因為有兩個,所以define複用性更高
    char ch1='\0',ch2='\0';
	geshi(T1,ch1);geshi(T2,ch2);
    o<<"{";//類似python的格式
    for(auto i=x.begin();i!=x.end();++i){
		//可以直接for(auto i:x),但是我不知道怎麼特判第一個來控制","
        o<<((i==x.begin())?"":", ") <<ch1<<i->first<<ch1<<": ";
        o<<ch2<<i->second<<ch2;
    }
    o<<"}"<<endl;
    return o;
    #undef geshi
}

int main()
{
    vector<int> k1={1,2,3,4};
    cout<<k1;
    vector<string> k2={"123","567","789"};
    cout<<k2;
    vector<char> k3={'a','b','c'};
    cout<<k3;
    
    cout<<endl;
    
    map<string,int> m1;
    m1["114"]=1,m1["514"]=2;
    cout<<m1;
    map<string,string> m2;
    m2["114"]="1919",m2["514"]="810";
    cout<<m2;    
}

下面開始講解。

本文作者XXOY

1.首先實現輸出一個vector的功能。

只需要遍歷一遍,逐個輸出就行了。

可以直接for(auto i:x)
但我要特判第一個不輸出逗號,所以還是使用for(int i=0;i<x.size();++i)
這樣進行遍歷。

2.給string加一個“”
為了區分string和int,通過特判輸出""

    string ch="";
    if(typeid(T)==typeid(string)) ch='\"';//特判string型別,用來加入“”
    if(typeid(T)==typeid(char)) ch='\'';

3.過載<<
這個前置芝士請百度。

我們用vector<T>過載

template<typename T>//模板的使用
ostream& operator<<(ostream &o,vector<T> &x){

4.聚合一下

template<typename T>//模板的使用
ostream& operator<<(ostream &o,vector<T> &x){
    string ch="";
    if(typeid(T)==typeid(string)) ch='\"';
    if(typeid(T)==typeid(char)) ch='\'';
    o<<"[";
    for(int i=0;i<x.size();++i){
        o<<((i==0)?"":", ") <<ch<<x[i]<<ch;
    }
    o<<"]"<<endl;
    return o;
}

這樣就可以實現了。
再如法炮製,把map的也寫了。

template<typename T1,typename T2>
ostream& operator<<(ostream &o,map<T1,T2> &x){
	#define geshi(x,ch) if(typeid(x)==typeid(string)) ch='\"';\
	if(typeid(x)==typeid(char)) ch='\''  
	//特判string型別,用來加入“,因為有兩個,所以define複用性更高
    char ch1='\0',ch2='\0';
	geshi(T1,ch1);geshi(T2,ch2);
    o<<"{";//類似python的格式
    for(auto i=x.begin();i!=x.end();++i){
		//可以直接for(auto i:x),但是我不知道怎麼特判第一個來控制","
        o<<((i==x.begin())?"":", ") <<ch1<<i->first<<ch1<<": ";
        o<<ch2<<i->second<<ch2;
    }
    o<<"}"<<endl;
    return o;
    #undef geshi
}

OK!

這麼做就可以實現一些騷操作了。

比如


int main()
{
    auto k=input().split();//k的型別是vector<string>
	cout<<k;
    auto c=my_map(my_int,k);//行,能用
    cout<<c;
}

這樣。

具體可以看我的其他文章。

input和split