C++ 逐渐 Python 化 已翻译 100%

fsxchen 投递于 2014/12/08 09:19 (共 6 段, 翻译完成于 12-09)
阅读 30512
收藏 118
6
加载中

近几年C++有了很多变化。最新的两个版本C++11和C++14,引入了如此多的新特性,用 Bjarne Stroustrup的话说就是“感觉就像一个新语言一样。”

真的。现代c++形成了一个全新的编程风格,我不能不注意到它带有更多的Python味道。基于范围(Range)的循环、类型推导、向量、map初始化和lambda表达式。你越是探索现代C++,你越能够发现它里面的Python痕迹。

是Python直接影响了现代C++吗?还是在C++传开前,Python已经采用了一些有用的结构?由你自己判断。

开源中国七里香
翻译于 2014/12/09 08:29
3

字面值

Python在2008年引入二进制字面值。现在C++14也有了。【更新:Thiago  Macieira在评论中指出,GCC实际上早在2007年就已经支持了。

static const int primes = 0b10100000100010100010100010101100;

Python早在1998年引入了 原始字符串字面值。在硬编码正则表达式或Windows路径时很方便。 C++11也添加了同样的特性,只是语法上略有不同:

const char* path = R"(c:\this\string\has\backslashes)";

基于范围的For循环(Range-Based For Loops)

在Python中,for循环总是迭代遍历一个Python对象:

for x in myList:
    print(x)

与此同时,在近30年里。C++仅支持C风格for循环。最后,在C++11中, 基于范围的for循环被添加进去。

for (int x : myList)
    std::cout << x;

与Python迭代协议不同,你可以迭代一个  std::vector  或任何实现了begin和end成员函数的类。有了基于范围的for循环后,我经常发现自己希望C++能内建像Python的xrange函数一样的函数。

开源中国七里香
翻译于 2014/12/09 08:48
2

自动化

Python一直以来都是一个动态类型语言。你不需要声明变量类型,因为类型是对象本身的属性。

x = "Hello world!"print(x)

从另一方面来说,C++不是动态类型语言。是静态类型。不过在C++11中将 auto 关键字 改作他用以用于类型推导,你能够写 看起来很像动态类型的代码:

auto x = "Hello world!";
std::cout << x;

当你调用重载几个类型的函数时,比如 std::ostream::operator<<  或者一个模板函数,C++更像一个动态类型语言。C++14进一步充实以支持auto关键字,为auto添加了 返回值支持和lambda函数 参数支持。

开源中国七里香
翻译于 2014/12/09 09:04
1

元组

Python从一开始就很好的定义了元组类型。当你需要把几个值整合在一起的时候,元组就非常适合,这样就再不需要命名类来实现同样的功能了。

triple = (5, 6, 7)
print(triple[0])

C++在C++11标准库中添加了对元组的支持。C++11的建议书 甚至还提到了这么做是受Python启发的:

C++

auto triple = std::make_tuple(5, 6, 7);
std::cout << std::get<0>(triple);

Pyton允许你把一个元组解析为多个独立的变量:

x, y, z = triple

在C++里,你可以使用std::tie实现同样的功能:

C++

std::tie(x, y, z) = triple;

统一的初始化

在Python里,列表是内置类型。因此,你可以只使用一个表达式来创建Python列表:

myList = [6, 3, 7, 8]
myList.append(5);

C++的向量(std::vector)与Python的列表最为相似。如今,C++11里新增的 统一的初始化可以让我们只使用一个表达式来创建向量和列表了:

C++

auto myList = std::vector<int>{ 6, 3, 7, 8 };
myList.push_back(5);

在Python里,你还可以只使用一个表达式来创建一个 字典

myDict = {5: "foo", 6: "bar"}
print(myDict[5])

与此类似,统一的初始化也适用于有序映射(std::map)和无序映射(unordered_map):

C++

auto myDict = std::unordered_map<int, const char*>{ { 5, "foo" }, { 6, "bar" } };
std::cout << myDict[5];
几点人
翻译于 2014/12/09 11:19
2

Lambda表达式

Python从1994年开始支持lambda函数


myList.sort(key = lambda x: abs(x))

Lambda表达式是在C++11中被添加进去。

std::sort(myList.begin(), myList.end(), [](int x, int y){ return std::abs(x) < std::abs(y); });

2001年,Python添加了 静态嵌套作用域,可以让lambda函数抓取定义在封闭函数内的变量。

def adder(amount):    return lambda x: x + amount
...
print(adder(5)(5))

同样,C++ lambda表达式支持一堆灵活的 抓取规则,可以让你做相似的事情:

auto adder(int amount) {    return [=](int x){ return x + amount; };
}
...
std::cout << adder(5)(5);

标准算法

Python内建  filter  函数可以让你有选择的从一个列表中拷贝项(虽然列表解析是首先):

result = filter(lambda x: x >= 0, myList)

C++11中 引入了  std::copy_if ,让你可以使用一个类似的、相当功能的类型:

auto result = std::vector<int>{};
std::copy_if(myList.begin(), myList.end(), std::back_inserter(result), [](int x){ return x >= 0; });

其他的C++ 算法模仿了Python的内建函数包括 transform、 any_of、 all_of, min 以及 max。即将到来的 范围提案有潜力进一步简化这些表达式。

开源中国七里香
翻译于 2014/12/09 09:27
1

参数打包

Python 从 1988 年就开始支持任意长度的参数列表. 你可以定义一个函数接受任意数量的实参,Python 会将他们放到一个元组(tuple)中, 你还可以将这个元组重新展开为一个实参列表,并把他们传递进另一个函数:

def foo(*args):    return tuple(*args)
...
triple = foo(5, 6, 7)

C++11 引入了对 参数包(parameter packs) 的支持. 它类似于 Python 的任意长度参数列表,而不同于 C 风格的可变参数列表, 这个参数包有自己的标识符来表示整个实参序列。关键区别在于:在 C++ 中,这个参数包不能在运行时做为一个单独的对象来操作。你只能通过模板元编程技术在编译时来操纵他们。

template <typename... T> auto foo(T&&... args) {    
    return std::make_tuple(args...);
}
...auto triple = foo(5, 6, 7);

并非所有的 C++ 11 和 14 中的特性都借鉴于 Python。只是其中很大一部分特性看似如此。 Python 被认为是一种对使用者亲近友好的编程语言。随着时间的推移以及这些特性逐渐被其他语言借鉴,它其中一些特质也逐渐暗淡下来。

你怎么看呢?C++ 中的这些新特性会不会使 C++ 更加简单,亲和,更具表现力呢?

泥牛
翻译于 2014/12/09 09:50
1
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(57)

小微b
小微b
越到后期学习c++的成本越大啊。奈何几年后我还是小菜比~☺
w_p_
w_p_
动态语言是编程语言发展的趋势
糯米饭团
糯米饭团

引用来自“张亦俊”的评论

还不如说像C#呢。
字面字符串,string a = @"c:\windows\system32";。
for each循环早就不是啥新奇货了。
类型推断,var a = "a"; auto是做类型推断的,python是动态类型的,差得十万八千里。
元祖这个,我实在不觉得在传统语言里这么干有意义,静态类型系统崩坏了,虽然C#也有。
初始化器,python是有内建列表的,但这个的性能无法预期,对于传统的C++而言毫无意义。
lambda表达式,var a = (a,b) => { return a;}
标准算法,这不是第三方库该干的事么……
参数打包,又一个静态类型崩坏的例子
同意
lython
lython

引用来自“Raymin”的评论

直接用 Python 不就得了,实在不行了,再用 C 写个模块调一调,齐了!

引用来自“itfanr”的评论

客户端程序还是c系列快吧

引用来自“Raymin”的评论

有空可以下载个 wxPython 或 pyQT,自己点点看。 没感到有啥区别。

引用来自“lython”的评论

pyqt和wx可以做做内部工具,或者给小公司用,尤其是gpl的pyqt,没有大公司会用的。python还是实用在服务端。

引用来自“Raymin”的评论

DropBox 算一个吧! NASA 算不? 再说大公司用不用管咱啥事?只要自己觉得好用就行。大公司有实力的,还自己开发操作系统呢!能比吗?
哥,我说的是Python不适合做客户端,适合做服务端!
Raymin
Raymin

引用来自“Raymin”的评论

直接用 Python 不就得了,实在不行了,再用 C 写个模块调一调,齐了!

引用来自“itfanr”的评论

客户端程序还是c系列快吧

引用来自“Raymin”的评论

有空可以下载个 wxPython 或 pyQT,自己点点看。 没感到有啥区别。

引用来自“lython”的评论

pyqt和wx可以做做内部工具,或者给小公司用,尤其是gpl的pyqt,没有大公司会用的。python还是实用在服务端。
DropBox 算一个吧! NASA 算不? 再说大公司用不用管咱啥事?只要自己觉得好用就行。大公司有实力的,还自己开发操作系统呢!能比吗?
lython
lython

引用来自“Raymin”的评论

直接用 Python 不就得了,实在不行了,再用 C 写个模块调一调,齐了!

引用来自“itfanr”的评论

客户端程序还是c系列快吧

引用来自“Raymin”的评论

有空可以下载个 wxPython 或 pyQT,自己点点看。 没感到有啥区别。
pyqt和wx可以做做内部工具,或者给小公司用,尤其是gpl的pyqt,没有大公司会用的。python还是实用在服务端。
开源中国射线科科长
开源中国射线科科长
C+Perl 岂不是轻松打败C+++Python? 效率 正则 要啥有啥 除了抽象层次稍微低了点,,但是高手也差那点层次 语言抽象的不足可以用动物抽象去弥补 难道语言不就是为了更好地描述这个世界吗?英语和C C++ 效率并不是最重要地 所以C一直没能干掉C++ 我看好C++
开源中国射线科科长
开源中国射线科科长

引用来自“Sail_鸢”的评论

其实本质上就是 函数是否是一类公民?
函数不过是对过程对封装而已 编程本质还是for if else的重用 在这个意义上 函数和方法本来就应该是一类公民嘛~
您的好友
您的好友
各种语言相互借鉴 没啥问题吧
哆啦比猫
哆啦比猫
等 rust 完工了马上转过去,现在还是得用 c++
py这种动态语言还是算了
返回顶部
顶部