Golang部份特性的C++对比实现
今天看到一篇文章<<C++ 逐渐 Python 化>>, 我个人是认为这个说法是不成立的,但这里面的一些特性对比引起了我的兴趣。 我想尝试下,Go语言所带的一些东西,在C++11中是如何做的,应当很有意思。所以刷刷刷,就有了下面的东西。 目录: 字符串字面值
字面值这个东西在两种语言中都有比较好的解决方式.Go语言用" ` "符号,C++使用R(" )"这种方式。可以省掉不少转义符的输入。 Golang
path := `c:abcGG再也不用烦转义符了` mulln := `"(C++/Golang aa'aaaCplusplus/gogogo author"xiongchuanliang ` fmt.Println(path) fmt.Println(mulln)C++
string path = R"(c:abcGG再也不用烦转义符了)"; cout << "单行:" << path.c_str() << endl; string muln = R"(C++/Golang aa'aaaCplusplus/gogogo author"xiongchuanliang )"; cout << "多行:" << muln.c_str() << endl; 变量初始化现在开发语言的初始化都差不多,都能很方便的定义时初始化,循环也是如下面中的C++ for循环和Go语言中的"for : rang" 形式基本一样。 另外C++的auto,Go语言中的":=",都能省代码的好东西。不过要多提一句,Go语言支持多重赋值,并且变量都 是默认就已初始化好。同时,Go语言也支持指针,但它的指针要安全得多。 Golang var k int fmt.Println(k) mArr := []int{ 1,2,3} var mMap = map[string]int {"a":1,"b":2} fmt.Printf("array:%vnmap:%v n",mArr,mMap) i := 10 pi := &i //*i ppi := &pi //**int fmt.Println(i,*pi,**ppi) //结果: 0 array:[1 2 3] map:map[a:1 b:2] 10 10 10 C++ int mArr[] = { 1,3 }; auto mList = vector < int > {1,3,4}; auto mMap = map < int,string > {{1,"aa"},{ 2,"bb" }}; cout << "vector: "; for (const int& x : mList) cout << x << " "; cout << endl; cout << "map: "; for (const auto& mp : mMap) cout << mp.first << " " << (mp.second).c_str(); cout << endl;
lambdalambda这东西在C++11中可是重点推荐的特性,非常的强大。Go语言自然也有,但对于匿名函数中函数外部变量的处理 并没有C++那么多种。 像C++分了四类: [a,&b] a变量以值的方式呗捕获,b以引用的方式被捕获。 而Go语言默认就相当于"[=]",即,捕获可见范围内所有的外部变量。 Golang mArr := []int{ 1,3} fun := func(i,v int){ fmt.Printf("idx:%d value:%d n",i,v) } for idx,val := range mArr{ fun(idx,val) } C++ int arr[] = { 1,3 }; for_each(begin(arr),end(arr),[](int n){cout << n << endl; }); auto func = [](int n){cout << n << endl; }; for_each(begin(arr),func);
值顺序递增(iota)iota这个小东西很有特点,两种语言都支持且都是让数据顺序递增,从功能上看C++的iota似乎更强大灵活些。 但有意思的是, 似乎在Go语言中,iota的使用频率要高得多,被大量的用于像const定义之类的地方,有意思。 Golang const ( Red = iota Green Blue ) fmt.Println("Red:",Red," Gree:",Green," Blue:",Blue); C++ int d[5] = { 0 }; std::iota(d,d + 5,10); cout << "iota_demo(): old : d[5] = { 0 } "<< endl; cout << "iota_demo(): iota: d[5] = { "; for each (int var in d) { cout << var <<" "; } cout <<"} "<< endl; char e[5] = { 'a' }; char f[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_t i = 0; i < 5; i++) { cout <<" iota = " << e[i] << endl; } //结果: 值顺序递增 iota_demo(): old : d[5] = { 0 } iota_demo(): iota: d[5] = { 10 11 12 13 14 } 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 func tuple_demo()(int,string){ a,b := 1,2 fmt.Println("a:",a," b:",b); c,d := b,a fmt.Println("c:",c," d:",d); return 168,"函数返回的字符串" }C++ tuple<int,string> tuple_demo(){ tuple<int,string> ret; ret = make_tuple(168,"函数返回的字符串"); cout << "tuple_demo(): " << get<0>(ret) << " " << (get<1>(ret)).c_str() << endl; auto triple = make_tuple(5,6,7); cout << "tuple_demo(): " << get<0>(triple) << " " << get<1>(triple) << " " << get<2>(triple) << endl; int ti; string ts; tie(ti,ts) = make_tuple(10,"xcl--将数字和字符赋值给两个变量"); cout << "tuple_demo(): " << ti << " " << ts.c_str() << endl; return ret; } //调用: int ti; string ts; tie(ti,ts) = tuple_demo(); cout << "main() <- tuple_demo(): " << ti << " " << ts.c_str() << endl; //结果: 多值赋值及函数返回多值 tuple_demo(): 168 函数返回的字符串 tuple_demo(): 5 6 7 tuple_demo(): 10 xcl--将数字和字符赋值给两个变量 main() <- tuple_demo(): 168 函数返回的字符串 多值赋值及函数返回多值 end. map查找Go语言中map的查找特别方便. 要找个值,直接map[key]就出来了。C++也可以直接用find(key)的方式,但Go语言直接有个 found的变量,能告知是否有找到,这个要比C++去比end(),要直观些,也可以少打些字。 Golang var mMap = map[string]int {"a":1,"b":2,"c":3} val,found := mMap["b"] if found { fmt.Println("found :",val); }else{ fmt.Println("not found"); } C++ typedef map <string,int > map_str_int; tuple<string,int,bool> mapfind_demo(map_str_int myMap,string key){ map_str_int::iterator pos; pos = myMap.find(key); if (pos == myMap.end()){ return make_tuple("",false); } else{ return make_tuple(pos->first,pos->second,true); } } //调用: auto myMap = map_str_int{ { "aa",1 },{ "bb",2 },{ "cc",3 } }; string mpKey; int mpValue; bool mpFound = false; tie(mpKey,mpValue,mpFound) = mapfind_demo(myMap,"bb"); if (mpFound){ cout << "mapfind_demo: found" << endl; } else{ cout << "mapfind_demo: not found" << endl; } 可变参数可变参数是指函数的最后一个参数可以接受任意个参数,我在用Go语言实现的args_demo()例子中,用了效果一样的两种不同 调用方法来展示Go语言对这个下的功夫。然后可以再看看通过C++模板实现的,一个比较有代表性的Print函数来感受感受C++ 对这个可变参数的处理方式。 Golang func args_demo(first int,args ...int){ fmt.Println("ars_demo first:",first) for _,i := range args { fmt.Println("args:",i) } } //调用 args_demo(5,7,8); mArr := []int{ 5,8} args_demo(mArr[0],mArr[1:]...); fmt.Println("fmtPrintln(): ",1,2.0,"C++11","Golang"); 执行结果 变量fmtPrintln(): 1 2 C++11 Golang ars_demo first: 5 args: 6 args: 7 args: 8 ars_demo first: 5 args: 6 args: 7 args: 8 C++ template<typename T> void fmtPrintln(T value){ cout << value << endl; } template<typename T,typename... Args> void fmtPrintln(T head,Args... args) { cout << head << " "; fmtPrintln(args...); } //调用 fmtPrintln("fmtPrintln(): ","Golang"); //执行结果: 变长参数 fmtPrintln(): 1 2 C++11 Golang 变长参数 end. 回调函数对比看看两种语言函数的回调处理,实现方法没啥差异。 Golang type funcType func(string) func printFunc(str string){ fmt.Println( "callFunc() -> printFunc():",str) } func callFunc(arg string,f funcType){ f(arg) } callFunc("回调就是你调我,我调它,大家一起玩。",printFunc)
C++ void printFunc(string arg){ cout << "callFunc() -> printFunc():" << arg.c_str() << endl; } typedef void(*callf)(string); void callFunc(callf pFunc,string arg){ //void(*pFunc)(string) pFunc(arg); } callFunc(printFunc,"回调就是你调我,我调它,大家一起玩。");
泛型C++泛型就不用多说了,都知道有多强大。Go语言要加入这个不知道是啥时候的事,不过通过简单的反射,还 是可以实现类似的功能,但代码有点长。 Golang func compare(v1,v2 interface{}) (int,error) { switch v1.(type) { case int: if v1.(int) < v2.(int) { return -1,nil } else if v1.(int) == v2.(int) { return 0,nil } case int8: if v1.(int8) < v2.(int8) { return -1,nil } else if v1.(int8) == v2.(int8) { return 0,nil } case int32: if v1.(int32) < v2.(int32) { return -1,nil } else if v1.(int32) == v2.(int32) { return 0,nil } //省略...... default: return -2,errors.New("未能处理的数据类型.") } return 1,nil } //调用: v1 := 13 v2 := 53 ret,err := compare(v1,v2) if err != nil { fmt.Println(err) return } switch ret { case -1: fmt.Println("v1 < v2") case 0: fmt.Println("v1 == v2") case 1: fmt.Println("v1 > v2") default: fmt.Println("defualt") } C++ template <typename T> int compare(const T v1,const T v2){ if (v1 < v2){ cout << "compare(): v1 < v2" << endl; return -1; } else if (v1 == v2){ cout << "compare(): v1 == v2" << endl; return 0; } else{ cout << "compare(): v1 > v2" << endl; return 1; } } //调用: int i1 = 5,i2 = 7; double d1 = 52.5,d2 = 10.7; compare(i1,i2); compare(d1,d2);
数组和切片(sclie)数组/切片Go语言做得非常灵活,不一一举例,这里主要可以看看C++的。我用copy_n,copy_if 模拟二下简单的切片功能。 Golang a := [5]int{ 1,4,5 } b := a[:3] c := a[1:2] fmt.Println(a) fmt.Println(b) fmt.Println(c) //运行结果:<span style="white-space:pre"> </span> [1 2 3 4 5] [1 2 3] [2] C++ int a[5] = { 1,5 }; int b[3] = { 0 }; int c[2] = { 0 }; cout << "a[5] = { 1,5 }" << endl; cout << "array[:end_pos]: b = array[:3]" << endl; // array[:end_pos] copy_n(a,b); for each (int var in b) { cout << " " << var; } cout << endl; cout << "a[5] = { 1,5 }" << endl; cout << "array[begin_pos:end_pos]: c = array[1,2] " << endl; // array[begin_pos:end_pos] int begin_pos = 1; int subLen = sizeof(c) / sizeof(c[0]); int end_pos = begin_pos + subLen; copy_if(a + begin_pos,a + end_pos,[](int v){return true; }); for each (int var in c) { cout << " " << var ; } cout << endl; //运行结果: 数组和切片(sclie) a[5] = { 1,5 } array[:end_pos]: b = array[:3] 1 2 3 a[5] = { 1,5 } array[begin_pos:end_pos]: c = array[1,2] 2 3 数组和切片(sclie) end. 很粗浅的分别实现下这几个点,体会是C++很强大,Golang更纯粹,少即是多。 Go语言和C++完整测试源码我放在此: 点击下载 可以自行下载编译。
MAIL: xcl_168@aliyun.com Blog:http:/blog.csdn.net/xcl168 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |