今天看到一篇文章<<C++ 逐渐 Python 化>>, 我个人是认为这个说法是不成立的,但这里面的一些特性对比引起了我的兴趣。
我想尝试下,Go语言所带的一些东西,在C++11中是如何做的,应当很有意思。所以刷刷刷,就有了下面的东西。
目录:
字符串字面值 变量初始化 lambda 值顺序递增 多值赋值及函数返回多值 map查找 可变参数 回调函数 泛型 数组和切片
字面值
这个东西在两种语言中都有比较好的解决方式.Go语言用" ` "符号,C++使用R(" )"这种方式。可以省掉不少转义符的输入。
Golang
- path:=`c:abcGG再也不用烦转义符了`
- mulln:=`"(C++/Golang
- aa'aaaCplusplus/gogogo
- author"xiongchuanliang
- `
- fmt.Println(path)
- fmt.Println(mulln)
C++
变量初始化
现在开发语言的初始化都差不多,都能很方便的定义时初始化,循环也是如下面中的C++ for循环和Go语言中的"for : rang"
形式基本一样。 另外C++的auto,Go语言中的":=",都能省代码的好东西。不过要多提一句,Go语言支持多重赋值,并且变量都
是默认就已初始化好。同时,Go语言也支持指针,但它的指针要安全得多。
Golang
copy
varkint
fmt.Println(k)
mArr:=[]int{1,2,3}
varmMap=map[string]int{"a":1,"b":2}
fmt.Printf("array:%vnmap:%vn",mArr,mMap)
i:=10
pi:=&i
ppi:=&pi
fmt.Println(i,*pi,**ppi)
0
array:[123]
map:map[a:1b:2]
101010
C++
copy
intmArr[]={1,3};
automList=vector<int>{1,3,4};
automMap=map<int,string>{{1,"aa"},{2,"bb"}};
cout<<"vector:";
for(constint&x:mList)
cout<<x<<"";
cout<<endl;
cout<<"map:";
constauto&mp:mMap)
cout<<mp.first<<""<<(mp.second).c_str();
cout<<endl;
lambda
lambda这东西在C++11中可是重点推荐的特性,非常的强大。Go语言自然也有,但对于匿名函数中函数外部变量的处理
并没有C++那么多种。 像C++分了四类:
[a,&b] a变量以值的方式呗捕获,b以引用的方式被捕获。 [this] 以值的方式捕获 this 指针。 [&] 以引用的方式捕获所有的外部自动变量。 [=] 以值的方式捕获所有的外部自动变量。 [] 不捕获外部的任何变量。
而Go语言默认就相当于"[=]",即,捕获可见范围内所有的外部变量。
Golang
copy
mArr:=[] fun:=func(i,vint){
fmt.Printf("idx:%dvalue:%dn",i,v)
}
foridx,val:=rangemArr{
fun(idx,val)
}
C++
copy
intarr[]={1,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> for_each(begin(arr),end(arr),[](intn){cout<<n<<endl;});
autofunc=[](intn){cout<<n<<endl;};
for_each(begin(arr),func);
值顺序递增(iota)
iota这个小东西很有特点,两种语言都支持且都是让数据顺序递增,从功能上看C++的iota似乎更强大灵活些。 但有意思的是,
似乎在Go语言中,iota的使用频率要高得多,被大量的用于像const定义之类的地方,有意思。
Golang
copy
const(
Red=iota
Green
Blue
)
fmt.Println("Red:",Red,"Gree:",Green,"Blue:",Blue);
C++
copy
intd[5]={0};
std::iota(d,d+5,10);
cout<<"iota_demo():old:d[5]={0}"<<endl;
cout<<"iota_demo():iota:d[5]={";
foreach(intvarind)
{
cout<<var<<"";
}
cout<<"}"<<endl;
chare[5]={'a'};
charf[5]={0};
copy_n(e,5,f);
cout<<"iota_demo():old:e[5]={'a'}"<<endl;
cout<<"iota_demo():iota:e[5]"<<endl;
std::iota(e,e+5,'e');
for(size_ti=0;i<5;i++)
{
cout<<"iota="<<e[i]<<endl;
值顺序递增
iota_demo():old:d[5]={0}
iota_demo():iota:d[5]={1011121314}
iota_demo():old:e[5]={'a'}
iota_demo():iota:e[5]
iota=e
iota=f
iota=g
iota=h
iota=i
值顺序递增end.
多值赋值及函数返回多值
这个功能在Go语言中相当方便,C++中则需要使用tuple和 tie等才能实现,有点麻烦,但效果是一样的。
Golang
copy
functuple_demo()( a,b:=1,2
fmt.Println("a:",a,"b:",b);
c,d:=b,a
fmt.Println("c:",c,"d:",d);
return168,"函数返回的字符串"
}
C++
copy
tuple< tuple< ret=make_tuple(168,"函数返回的字符串");
cout<<"tuple_demo():"<<get<0>(ret)<<""<<(get<1>(ret)).c_str()<<endl;
autotriple=make_tuple(5,6,7);
cout<<"tuple_demo():"<<get<0>(triple)<<""<<get<1>(triple)<<""<<get<2>(triple)<<endl;
intti;
stringts;
tie(ti,ts)=make_tuple(10,"xcl--将数字和字符赋值给两个变量");
cout<<"tuple_demo():"<<ti<<""<<ts.c_str()<<endl;
returnret;
intti;
stringts;
tie(ti,ts)=tuple_demo();
cout<<"main()<-tuple_demo():"<<ti<<""<<ts.c_str()<<endl;
//结果:
多值赋值及函数返回多值
tuple_demo():168函数返回的字符串
tuple_demo():567
tuple_demo():10xcl--将数字和字符赋值给两个变量
main()<-tuple_demo():168函数返回的字符串
多值赋值及函数返回多值end.
map查找
Go语言中map的查找特别方便. 要找个值,直接map[key]就出来了。C++也可以直接用find(key)的方式,但Go语言直接有个
found的变量,能告知是否有找到,这个要比C++去比end(),要直观些,也可以少打些字。
Golang
copy
varmMap=map[string]"b":2,"c":3}
val,found:=mMap["b"]
iffound{
fmt.Println("found:",val);
}else{
fmt.Println("notfound");
copy
typedefmap<string,int>map_str_int;
tuple<string,bool>mapfind_demo(map_str_intmyMap,stringkey){
map_str_int::iteratorpos;
pos=myMap.find(key);
if(pos==myMap.end()){
returnmake_tuple("",false);
returnmake_tuple(pos->first,pos->second,153); background-color:inherit; font-weight:bold">true);
//调用:
automyMap=map_str_int{{"aa",1},{"bb",2},{"cc",3}};
stringmpKey;
intmpValue;
boolmpFound=false;
tie(mpKey,mpValue,mpFound)=mapfind_demo(myMap,"bb");
if(mpFound){
cout<<"mapfind_demo:found"<<endl;
cout<<"mapfind_demo:notfound"<<endl;
}
可变参数
可变参数是指函数的最后一个参数可以接受任意个参数,我在用Go语言实现的args_demo()例子中,用了效果一样的两种不同
调用方法来展示Go语言对这个下的功夫。然后可以再看看通过C++模板实现的,一个比较有代表性的Print函数来感受感受C++
对这个可变参数的处理方式。
Golang
copy
funcargs_demo(firstint){
fmt.Println("ars_demofirst:",first)
for_,i:=rangeargs{
fmt.Println("args:",i)
//调用
args_demo(5,7,8);
int{5,8}
args_demo(mArr[0],mArr[1:]...);
fmt.Println("fmtPrintln():",1,2.0,"C++11","Golang");
执行结果
变量fmtPrintln():12C++11Golang
ars_demofirst:5
args:6
args:7
args:8
args:8
copy
template<typenameT>voidfmtPrintln(Tvalue){
cout<<value<<endl;
typenameT,153); background-color:inherit; font-weight:bold">typename...Args>
voidfmtPrintln(Thead,Args...args)
cout<<head<<"";
fmtPrintln(args...);
fmtPrintln("fmtPrintln():",0); background-color:inherit">//执行结果:
变长参数
fmtPrintln():12C++11Golang
变长参数end.
回调函数
对比看看两种语言函数的回调处理,实现方法没啥差异。
copy
typefuncTypefunc(string)
funcprintFunc(strstring){
fmt.Println("callFunc()->printFunc():",str)
funccallFunc(argstring,ffuncType){
f(arg)
callFunc("回调就是你调我,我调它,大家一起玩。",printFunc)
C++
copy
voidprintFunc(stringarg){
cout<<"callFunc()->printFunc():"<<arg.c_str()<<endl;
typedefvoid(*callf)(string);
voidcallFunc(callfpFunc,stringarg){
pFunc(arg);
callFunc(printFunc,"回调就是你调我,我调它,大家一起玩。");
泛型
C++泛型就不用多说了,都知道有多强大。Go语言要加入这个不知道是啥时候的事,不过通过简单的反射,还
是可以实现类似的功能,但代码有点长。
Golang
copy
funccompare(v1,v2interface{})(switchv1.(type){
caseint:
ifv1.(int)<v2.(return-1,nil
elseint)==v2.(return0,153); background-color:inherit; font-weight:bold">caseint8:
ifv1.(int8)<v2.(int8){
ifv1.(int8)==v2.(int8){
caseint32:
ifv1.(int32)<v2.(int32){
ifv1.(int32)==v2.(int32){
//省略......
default:
return-2,errors.New("未能处理的数据类型.")
return1,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> v1:=13
v2:=53
ret,err:=compare(v1,v2)
iferr!=nil{
fmt.Println(err)
return
switchret{
case-1:
fmt.Println("v1<v2")
case0:
fmt.Println("v1==v2")
case1:
fmt.Println("v1>v2")
default:
fmt.Println("defualt")
}
C++
copy
typenameT>intcompare(constTv1,153); background-color:inherit; font-weight:bold">constTv2){
if(v1<v2){
cout<<"compare():v1<v2"<<endl;
return-1;
if(v1==v2){
cout<<"compare():v1==v2"<<endl;
return0;
else{
cout<<"compare():v1>v2"<<endl;
return1;
inti1=5,i2=7;
doubled1=52.5,d2=10.7;
compare(i1,i2);
compare(d1,d2);
数组和切片(sclie)
数组/切片Go语言做得非常灵活,不一一举例,这里主要可以看看C++的。我用copy_n,copy_if 模拟二下简单的切片功能。
Golang
copy
a:=[5] b:=a[:3]
c:=a[1:2]
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
//运行结果:<spanstyle="white-space:pre"></span>
[12345]
[123]
[2]
copy
inta[5]={1,5};
intb[3]={0};
intc[2]={0};
cout<<"a[5]={1,5}"<<endl;
cout<<"array[:end_pos]:b=array[:3]"<<endl;
//array[:end_pos]
copy_n(a,b);
intvarinb)
cout<<""<<var;
cout<<"a[5]={1,5}"<<endl;
cout<<"array[begin_pos:end_pos]:c=array[1,2]"<<endl;
//array[begin_pos:end_pos]
intbegin_pos=1;
intsubLen=sizeof(c)/sizeof(c[0]);
intend_pos=begin_pos+subLen;
copy_if(a+begin_pos,a+end_pos,87); background-color:inherit; font-weight:bold">intv){returntrue;});
intvarinc)
cout<<""<<var;
cout<<endl;
//运行结果:
数组和切片(sclie)
a[5]={1,5}
array[:end_pos]:b=array[:3]
123
a[5]={1,5}
array[begin_pos:end_pos]:c=array[1,2]
23
数组和切片(sclie)end.
很粗浅的分别实现下这几个点,体会是C++很强大,Golang更纯粹,少即是多。
Go语言和C++完整测试源码我放在此:点击下载
可以自行下载编译。 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|