当前位置: 首页 > news >正文

可以做网络兼职的网站seo搜索引擎优化薪资水平

可以做网络兼职的网站,seo搜索引擎优化薪资水平,莱芜在线论坛话题牛泉镇,中国最好的网站建设使用 Lambda 使代码更具表现力 一、Lambda VS. 仿函数二、总结 一、Lambda VS. 仿函数 Lambda 是 C11 中最引人注目的语言特性之一。它是一个强大的工具,但必须正确使用才能使代码更具表现力,而不是更难理解。 首先,要明确的是,…

使用 Lambda 使代码更具表现力

  • 一、Lambda VS. 仿函数
  • 二、总结

一、Lambda VS. 仿函数

Lambda 是 C++11 中最引人注目的语言特性之一。它是一个强大的工具,但必须正确使用才能使代码更具表现力,而不是更难理解。

首先,要明确的是,Lambda 并没有为语言添加新的功能。任何可以用 Lambda 完成的事情,都可以用仿函数(Functor)来完成,虽然仿函数的语法更繁琐,需要更多的类型声明。

例如,比较检查一个整数集合中所有元素是否都在两个整数 a 和 b 之间的两种方式:

  • 仿函数。
  • Lambda 表达式。

仿函数版本:

class IsBetween
{
public:IsBetween(int a, int b) : a_(a), b_(b) {}bool operator()(int x) { return a_ <= x && x <= b_; }
private:int a_;int b_;
};bool allBetweenAandB = std::all_of(numbers.begin(), numbers.end(), IsBetween(a, b));

Lambda 版本:

bool allBetweenAandB = std::all_of(numbers.begin(), numbers.end(),[a,b](int x) { return a <= x && x <= b; });

很明显,Lambda 版本更简洁,更易于编写,这可能是 Lambda 在 C++ 中备受关注的原因。

对于像检查一个数字是否在两个边界之间这样简单的操作,许多人可能会同意 Lambda 是更好的选择。但也并非所有情况下都是如此。

除了编写和简洁性之外,在前面的例子中,Lambda 和仿函数之间的两个主要区别是:

  • Lambda 没有名字。
  • Lambda 不隐藏其代码,而是直接在调用点展示。

但是,通过调用具有有意义名称的函数将代码从调用点移出,是管理抽象级别的一种基本技巧。但是,上面的例子是可以接受的,因为这两个表达式:

IsBetween(a, b)

[a,b](int x) { return a <= x && x <= b; }

读起来很相似。它们的抽象级别是一致的。

但是,当代码变得更加复杂时,结果就会大不相同,以下例子将说明这一点。

一个表示盒子的类的例子,它可以根据尺寸和材质(金属、塑料、木材等)进行构建,并提供对盒子特性的访问:

class Box
{
public:Box(double length, double width, double height, Material material);double getVolume() const;double getSidesSurface() const;Material getMaterial() const;
private:double length_;double width_;double height_;Material material_;
};

有一个这样的盒子集合:

std::vector<Box> boxes = ....

想要选择能够安全地容纳某种产品(水、油、果汁等)的盒子。

通过一些物理推理,可以近似地将产品对盒子四个侧面的压力视为产品的重量,它分布在这些侧面的表面上。如果材料能够承受施加的压力,则盒子足够坚固。

假设材料可以承受的最大压力为:

class Material
{
public:double getMaxPressure() const;....
};

产品提供了它的密度,以便计算它的重量:

class Product
{
public:double getDensity() const;....
};

现在,要选择能够安全地容纳产品 product 的盒子,可以使用 STL 和 Lambda 编写以下代码:

std::vector<Box> goodBoxes;
std::copy_if(boxes.begin(), boxes.end(), std::back_inserter(goodBoxes),[product](const Box& box){const double volume = box.getVolume();const double weight = volume * product.getDensity();const double sidesSurface = box.getSidesSurface();const double pressure = weight / sidesSurface;const double maxPressure = box.getMaterial().getMaxPressure();return pressure <= maxPressure;});

以下是等效的仿函数定义:

class Resists
{
public:explicit Resists(const Product& product) : product_(product) {}bool operator()(const Box& box){const double volume = box.getVolume();const double weight = volume * product_.getDensity();const double sidesSurface = box.getSidesSurface();const double pressure = weight / sidesSurface;const double maxPressure = box.getMaterial().getMaxPressure();return pressure <= maxPressure;}
private:Product product_;
};

在主代码中:

std::vector<Box> goodBoxes;
std::copy_if(boxes.begin(), boxes.end(), std::back_inserter(goodBoxes), Resists(product));

尽管仿函数仍然需要更多的类型声明,但使用仿函数的算法代码行看起来比使用 Lambda 更清晰。不幸的是,对于 Lambda 版本来说,这一行代码更重要,因为它是主要代码。

在这里,Lambda 的问题在于它展示了如何进行盒子检查,而不是简单地说检查已经完成,因此它的抽象级别太低了。在该示例中,它会影响代码的可读性,因为它迫使读者深入 Lambda 的主体以弄清楚它做了什么,而不是简单地说明它做了什么。

在这里,有必要将代码从调用点隐藏,并为它赋予一个有意义的名称。仿函数在这方面做得更好。

但这是否意味着不应该在任何非平凡的情况下使用 Lambda?当然不是。

Lambda 被设计得比仿函数更轻便、更方便,同时仍然保持抽象级别有序。这里的技巧是通过使用中间函数将 Lambda 的代码隐藏在一个有意义的名称后面。以下是 C++14 中实现此目的的方法:

auto resists(const Product& product)
{return [product](const Box& box){const double volume = box.getVolume();const double weight = volume * product.getDensity();const double sidesSurface = box.getSidesSurface();const double pressure = weight / sidesSurface;const double maxPressure = box.getMaterial().getMaxPressure();return pressure <= maxPressure;};
}

在这里,Lambda 被封装在一个函数中,该函数只是创建它并返回它。这个函数的作用是将 Lambda 隐藏在一个有意义的名称后面。

以下是主代码,它从实现负担中解脱出来:

std::vector<Box> goodBoxes;
std::copy_if(boxes.begin(), boxes.end(), std::back_inserter(goodBoxes), resists(product));

现在,为了使代码更具表现力,在本文的其余部分使用范围(Range)而不是 STL 迭代器:

auto goodBoxes = boxes | ranges::view::filter(resists(product));

当调用算法周围有其他代码时,隐藏实现的必要性变得更加重要。为了说明这一点,添加一个要求,即盒子必须从用逗号分隔的文本测量描述(例如,“16,12.2,5”)和所有盒子的唯一材料进行初始化。

如果直接调用即时 Lambda,结果将如下所示:

auto goodBoxes = boxesDescriptions| ranges::view::transform([material](std::string const& textualDescription){std::vector<std::string> strSizes;boost::split(strSizes, textualDescription, [](char c){ return c == ','; });const auto sizes = strSizes | ranges::view::transform([](const std::string& s) {return std::stod(s); });if (sizes.size() != 3) throw InvalidBoxDescription(textualDescription);return Box(sizes[0], sizes[1], sizes[2], material);})| ranges::view::filter([product](Box const& box){const double volume = box.getVolume();const double weight = volume * product.getDensity();const double sidesSurface = box.getSidesSurface();const double pressure = weight / sidesSurface;const double maxPressure = box.getMaterial().getMaxPressure();return pressure <= maxPressure;});

这变得非常难以阅读。但是,通过使用中间函数来封装 Lambda,代码将变成:

auto goodBoxes = textualDescriptions | ranges::view::transform(createBox(material))| ranges::view::filter(resists(product));

这才是希望代码呈现的样子。

请注意,这种技术在 C++14 中有效,但在 C++11 中略有不同。

Lambda 的类型没有在标准中指定,而是由编译器的实现决定。这里,auto 作为返回值类型允许编译器将函数的返回值类型写为 Lambda 的类型。但在 C++11 中,不能这样做,因此需要指定一些返回值类型。Lambda 可以隐式转换为具有正确类型参数的 std::function,并且可以在 STL 和范围算法中使用。请注意,std::function 会带来与堆分配和虚拟调用间接相关的额外成本。

在 C++11 中,resists 函数的建议代码将是:

std::function<bool(const Box&)> resists(const Product& product)
{return [product](const Box& box){const double volume = box.getVolume();const double weight = volume * product.getDensity();const double sidesSurface = box.getSidesSurface();const double pressure = weight / sidesSurface;const double maxPressure = box.getMaterial().getMaxPressure();return pressure <= maxPressure;};
}

请注意,在 C++11 和 C++14 的实现中,resists 函数返回的 Lambda 可能不会被复制,因为返回值优化可能会优化掉它。还要注意,返回 auto 的函数必须在其调用点可见。因此,这种技术最适合在与调用代码相同的文件中定义的 Lambda。

二、总结

  • 对于对抽象级别透明的函数,请使用在调用点定义的匿名 Lambda。
  • 否则,将 Lambda 封装在一个中间函数中。

在这里插入图片描述

http://www.shuangfujiaoyu.com/news/44725.html

相关文章:

  • 前端和后端哪个难seo网站查询
  • 网站建设公司排行榜全网营销系统怎么样
  • 北京做网站开发公司普通话的顺口溜6句
  • 胶南网站建设多少钱网站建设排名优化
  • 新网站一天做多少外链如何创建自己的个人网站
  • 看手表网站建个网站需要多少钱
  • 甘肃项目信息网网络seo公司
  • 个人可以做哪些网站谷歌优化教程
  • 手机阅读网站开发原因百度网盘登录入口官网
  • 景区网站建设要求福建seo快速排名优化
  • 科技创业创新心得seo线下培训课程
  • 岳阳政府网站建设公司关键词优化上海
  • 网站在线客服链接免费营销软件网站
  • 税务网站设计百度灰色关键词排名
  • 电子商务网站建设模板淘宝怎样优化关键词
  • 吉安网站优化汕头seo网络推广服务
  • 贵州中小型营销型网站建设公司免费的客户资源怎么找
  • 网站架构图怎么做推广赚佣金
  • 网站logo用什么来做湖北网站seo策划
  • 网站首页建设中页面湖南有实力seo优化
  • 长沙县 网站建设seo搜索引擎优化是通过优化答案
  • 人社部门网站建设商业策划公司十大公司
  • 哪个网站做二手车抵押seo网络营销
  • 贵阳做网站多少钱湖北seo公司
  • 张家口市住房和城乡建设局网站整合营销传播
  • 开发游戏用什么软件武汉seo公司出 名
  • 可以自己做网站卖东西苏州网络推广服务
  • 北京中邦亚通网站代写文章质量高的平台
  • 网站支付接口如何做外贸网站seo
  • 网站建设的公司合肥山东百度推广