[转]每个开发人员都应该知道的一些很棒的现代C ++功能

举报
Amrf 发表于 2021/03/22 20:42:06 2021/03/22
【摘要】 每个开发人员都应该知道的一些很棒的现代C ++功能(原文作者:Mottakin)作为一种语言,C ++已经发展了很多。当然,这并非一overnight而就。曾经有一段时间,C ++缺乏活力。很难喜欢这种语言。但是,当C ++标准委员会决定加快发展时,事情发生了变化。自2011年以来,C ++已经成为许多人一直期望的动态且不断发展的语言。不要误以为语言变得更容易了。它仍然是使用最广泛的最困难的...

每个开发人员都应该知道的一些很棒的现代C ++功能0_IttEgAi22EwkjY2h.jpg(原文作者:Mottakin)

作为一种语言,C ++已经发展了很多。

当然,这并非一overnight而就。曾经有一段时间,C ++缺乏活力。很难喜欢这种语言。

但是,当C ++标准委员会决定加快发展时,事情发生了变化。

自2011年以来,C ++已经成为许多人一直期望的动态且不断发展的语言。

不要误以为语言变得更容易了。它仍然是使用最广泛的最困难的编程语言之一,即使不是最困难的一种。但是C ++也比以前的版本更加易于使用。

在我的上一篇文章中,我谈到 了在过去几年中得到了丰富的 C ++算法库 (https://medium.freecodecamp.org/how-i-discovered-the-c-algorithm-library-and-learned-not-to-reinvent-the-wheel-2398a34e23e3)

今天,我们将研究每个开发人员都想知道的一些新功能(从C ++ 11开始,已经有8年的历史了)。

还要注意,我在本文中略过了一些高级功能,但是我愿意在将来写它们。🤞️

去!

当C ++ 11首次引入时 ,生活变得更加轻松。 auto

的想法 是让C ++编译器在编译时推断出数据的类型—而不是让您在 每次中断时都声明该类型 。 当您拥有 😛 这样的数据类型时,这非常方便 auto map<string,vector<pair<int,int>>>


1_FpIfC3i3C1XV5KyT0ZLYfw.png

查看行号5。没有,您不能声明某些内容 。这实际上是有道理的。第5行没有让编译器知道数据类型可以是什么。 initializer

最初,它 是有一定局限性的。然后,在该语言的更高版本中,添加了更多功能! auto


1_djxcpNzkBv4qWbG_FeE_eg.png

在第7和8行中,我使用了括号括起来的初始化。这也是C ++ 11中添加的新功能。

请记住,在使用的情况下, 编译器必须采用某种方式来推断出您的类型。 auto

现在是一个很好的问题, 如果我们写东西会 怎样?那是编译错误吗?那是向量吗? auto a = {1, 2, 3}

1_thcs9HD7UQrtWDeSWwTXGQ.jpeg

实际上,C ++ 11引入了 。如果声明,大括号初始化列表将被视为此轻量级容器 。 std::initializer_list<type> auto

最后,正如我之前提到的,当您具有复杂的数据结构时,由编译器进行类型推导可能非常有用:


1_2bUjEx0Uu9PCV_CJhFlWig.png

不要忘记签出第25行!该表达式 实际上是C ++ 17中的一个新功能。这称为 结构化绑定 。在该语言的早期版本中,您必须分别提取每个变量。但是结构化绑定使其更加方便。 auto [v1,v2] = itr.second

此外,如果您想使用引用获取数据,只需添加一个符号-即可 。 auto &[v1,v2] = itr.second

整洁的。

C ++ 11引入了lambda表达式,类似于JavaScript中的匿名函数。它们是函数对象,没有任何名称,并且它们 基于一些简洁的语法在各种 范围内 捕获变量 。它们也可以分配给变量。

如果您需要在代码中完成一些小的快速操作,但是您不愿意为此编写一个完整的单独函数,则Lambda非常有用。另一个很常见的用途是将它们用作比较功能。


1_bn-dG2MDn5rXgbYk9DZk1g.png

上面的例子有很多话要说。

首先,请注意花括号初始化如何为您增加负担。然后是通用的 ,这也是C ++ 11中的新增功能。然后,lambda函数用作数据的比较器。声明了lambda函数的参数,该参数 是在C ++ 14中添加的。在此之前,我们不能使用 函数参数。 begin(), end() auto auto

注意我们如何用方括号开始lambda表达式 。它们定义了lambda的范围-它对局部变量和对象有多少权限。 []

正如 现代C ++上这个 出色的存储库中 (https://github.com/AnthonyCalandra/modern-cpp-features#lambda-expressions)所定义的 :

  • [] -什么也没捕获。因此,您不能在lambda表达式内使用外部作用域的任何局部变量。您只能使用参数。
  • [=] —按值捕获作用域中的局部对象(局部变量,参数)。您可以使用它们,但不能修改它们。
  • [&] —通过引用捕获作用域中的局部对象(局部变量,参数)。您可以修改它们。像下面的例子。
  • [this]  this 按值捕获 指针。
  • [a, &b] — 通过引用 a  b 按值 捕获对象 。

因此,如果您想在lambda函数中将数据转换为其他格式,则可以利用作用域的优势来使用lambda。例如:


1_B2pwK3bNtKFcuGO1fLcztw.png

在上面的示例中,如果您 在lambda表达式中通过值()捕获了局部变量,则 无法 在第5行中进行更改 。因为简单地说,您无权执行此操作。不要滥用您的权利!😛 [factor] factor

最后,请注意我们 作为参考。这样可以确保lambda函数内部的任何更改实际上都会更改 。 val vector


0_0kU50Y_36U0Nw350.jpg



学习了现代C ++之后,他们会感到高兴!(照片由 Ian Schneider  Unsplash上 拍摄 

我一开始就很喜欢C ++ 17的这个功能。

1_LKpeYuEUJUc3-Zo8-F3y_w.png


因此,显然,您现在可以在 块内同时进行变量的初始化和检查条件 。这对于使代码简洁明了非常有帮助。通用形式为: if/switch

if( init-statement(x); condition(x)) {
// do some stuff here
} else {
// else has the scope of x
// do some other stuff
}

constexpr 很酷!

假设您有一些要评估的表达式,并且初始化后其值不会改变。您可以预先计算该值,然后将其用作宏。或者,如提供的C ++ 11一样,您可以使用 。 constexpr

程序员倾向于尽可能减少其程序的运行时间。因此,如果有一些操作可以使编译器完成并减轻运行时的负担,则可以改善运行时。

1_b_pmcPSAbckcVO7TEmF9tA.png


上面的代码是的非常常见的示例 。 constexpr

由于我们将fibonacci计算函数声明为 ,因此编译器可以 在编译时进行预计算 。所以编译后就可以替换行了 constexpr fib(20)

const long long bigval = fib(20); 

const long long bigval = 2432902008176640000;

请注意,传递的参数是一个 值。这是声明函数的重要点 -传递的参数也应该为 or 。否则,该函数将作为普通函数运行,这意味着在编译期间不会进行任何预先计算。 const constexpr constexpr const

变量也可以是 。如您所料,在那种情况下,这些变量必须在编译时可计算。否则,您将收到编译错误。 constexpr

有趣的是,后来在C ++ 17, 并 进行了介绍。 constexpr-if constexpr-lambda

就像一样 , 是各种数据类型的固定大小值的集合。 pair tuple

1_O0bsV0XdVhflKEm_1QB4Uw.png

有时使用 代替 会更方便 。 与普通的C类型数组相似,并具有C ++标准库的几个功能。此数据结构是在C ++ 11中添加的。 std::array tuple array

功能的非常冗长的名称。这个想法是,从C ++ 17开始,标准类模板也将进行模板的参数推导。以前,仅功能模板支持该功能。

因此,

std::pair<std::string, int> user = {"M", 25}; // previous
std::pair user = {"M", 25}; // C++17

推导的类型是隐式完成的。这对于变得更加方便 。 tuple

// previous
std::tuple<std::string, std::string, int> user ("M", "Chy", 25);
// deduction in action! 
std::tuple user2("M", "Chy", 25);

如果您不太熟悉C ++模板,则上述功能将毫无意义。

指针可能是地狱般的。

由于C ++之类的语言为程序员提供的自由度,有时候使自己陷入困境非常容易。在很多情况下,指针是造成危害的原因。

幸运的是,C ++ 11引入了智能指针,这些指针比原始指针要方便得多。它们通过尽可能释放内存来帮助程序员防止内存泄漏。它们还提供异常安全性。

我想在这篇文章中写有关C ++中的智能指针的文章。但是显然,关于它们有很多重要的细节。他们应有自己的职位,我当然愿意在不久的将来写一篇关于他们的文章。


今天就这些。请记住,C ++实际上在该语言的最新版本中添加了许多新功能。如果您有兴趣,应该检查一下。这是现代C ++上的一个很棒的存储库,其字面名称为 Awesome Modern C ++ (https://github.com/rigtorp/awesome-modern-cpp)

阿迪奥斯!

(原文:https://radiant-brushlands-42789.herokuapp.com/medium.com/free-code-camp/some-awesome-modern-c-features-that-every-developer-should-know-5e3bf6f79a3c)

----------------------------

在C ++ 11中move语义

1_zYzyNyTI1soUFT3TJ25zXQ.jpeg

Move语义是右值引用的第一个用例, 其主要目的 是将昂贵的复制操作替换为较便宜的移动操作,例如复制构造函数/复制赋值运算符可以帮助我们实现复制语义,移动构造函数/移动赋值运算符可以帮助我们实现移动语义,但是要了解此主题,我们首先需要了解左值,右值,左值引用和右值引用,然后我们才能讨论这一点。

左值和右值:

左值:通常是表达式,您可以使用例如命名变量的地址

Rvalues: 是不是Lvalues的那些表达式。他们大多是临时人员,其范围仅限于该陈述

例子

1. int x = 9;// x is lvalue and 9 is rvalue
2. auto emp = getEmployee(101); //emp is lvalue & getEmployee(101) expression and 101 is rvalue
3. processEmployee(emp);//passing lvaue to processEmployee
4. processEmployee(getEmployee(101));//passing rvalue to processEmployee
5. Employee& lemp = emp;//lemp is lvalue reference to lvalue emp
6. Employee&& remp = getEmployee(101); //remp is rvalue reference to rvalue getEmployee(101)
7. const Employee& cemp = getEmployee(101); //const reference to temporary(C++03)/rvalue(C++11)

所以现在我们很清楚Lvalues和Rvalues了,正如在示例5和6中看到的那样,C ++ 11中的lvalue引用和rvalue引用现在有两种类型的引用,以前我们只有一种引用类型,对于临时类型,我们需要使用const参考。

右值引用:正如我们在示例中看到的那样,它们在语法上是用两个&&编写的,顾名思义,它们仅绑定到右值,并且其主要目标是识别可从其移出的对象。

int y = 10;

这里需要注意的一点是x和r本身是左值,其类型是右值引用,并且它们是左值,因为它们具有名称(x和r),其次我们可以获取它们的地址,并且它们的寿命也超出此行。所以在这之后,如果我们做int && temp = r; 那么这将是错误的,因为r是不能由rvalue reference引用的左值

移动语义:

现在掌握了左值,右值,左值引用(c ++ 98的引用)和右值引用的知识,让我们跳到Move Semantics(在右值引用的帮助下实现),并了解一个例子:

0_0eFQ197ElsN7_6wX.jpg

请记住此示例,以更好地理解此博客文章

所以这里的getMyParser是工厂函数,它将基于传递给函数的第一个参数创建OptionParser或FutureParser对象,第二个参数是const引用,以便它可以同时获取左值和右值,然后将其转发给类的构造函数。完美,但是如果xml解析器的工作是解析巨大的输入xml(将它作为字符串传递给工厂函数,然后作为对构造函数的引用传递给我们,我们将使用该类构造函数初始化类std :: string成员函数作为下面的快速参考)是FutureXML班级 :

0_pY25cHh_iKPGIgXz.jpg


因此,如果按以下方式调用工厂函数,则一切都很好:

std::string bigFutureXML ("This is test xml..........");

因为bigFutureXML在这里是左值,即使在函数调用后我们也不想保留它,所以在m_sfutureXML中复制它很有意义,但是如果函数调用如下:

auto xmlParser = getMyParser(1,std::string("This is test xml......."));

这里的第二个参数是右值,将其复制到类成员函数中是不合逻辑的,因为此右值在此行之后就被销毁了。因此,在这里我们不必调用昂贵的std :: string复制构造函数,并且效率低下,并且由于c ++都是关于效率的,所以在新的c ++ 11中,他们引入了移动语义(通过rvalue引用实现),从而可以移动rvalue而不是被复制。作为示例,这是我们如何实现FutureParser rvalue重载构造函数的方法:

0_46ZyCEqlKAL0u2ZI.jpg


现在,如果我们调用工厂函数,如下所示:

auto xmlParser = getMyParser(1,std::string("This is test xml......."));

那么它将调用FutureParser构造函数的右值重载对吗?

不,记住getMyParser,我们在其中调用类构造函数,如新的FutureParser(arg_sInputXML),此时arg_sInputXML是左值,左值未绑定到右值引用,因此它将调用类左值参数化的构造函数,而不是该值,所以我们该怎么办这样就可以调用该类的右值构造函数,答案是将arg_sInputXML从左值转换为右值,这可以通过std :: move实现。

当arg_sInputXML转换为rvalue时,将调用std :: string move构造函数,并将原始arg_sInputXML渲染为无用,而m_sfutureXML将包含该字符串。这种方法不是很好,因为它将使该左值无效,并且在函数调用后使用该值会导致未定义的行为,因此我们要做的是再编写一个仅对右值有效的重载,如下所示:


0_fS7rKRVmkp8OWtjP.jpg

请记住,std::move不会移动任何东西,它只是将左值转换为右值的静态转换,对于右值类,移动构造函数被调用,效率更高,其效率的原因及其实现方式将在其他部分进行解释博客文章。

(原文:https://medium.com/@kpl.vermani/move-semantics-in-c-11-a0b836a8b4fa)

------------

用C ++的功能方式做到这一点

(原文作者:Sheik Arbaz)

在毕业的日子里,我花了一些时间在C ++上做竞争性编程。但是我从来没有机会在我的办公室项目中使用C ++,而是用函数式编程(FP)语言进行编码。但是两年后,我有机会从事C ++工作。作为一个非常喜欢凉爽的FP风格(使开发人员的工作变得轻松)的函数式编程爱好者,我开始探索在C ++中以FP风格进行编码的方法。我了解到C ++在最新版本中具有惊人的功能。在此博客中,我们将介绍函数式编程的基础知识,以及在C ++中可能实现的哪些部分。

先决条件:

  • 一点C ++经验
  • 具备任何函数式编程语言或范例的经验
  • 支持C ++ 11标准的C ++编译器

让我们开始吧

函数式编程是一种声明式的编程风格。与命令式风格相反,命令式风格只关注“如何解决”,而它的唯一关注点是“解决什么”。它使用表达式而不是语句。

功能编程关键概念

  • 用作一流对象
  • 纯功能

功能性编程规则

  • 不可变的变量:在函数式编程中,您无法在变量初始化后对其进行修改。你就是不行 您可以创建新变量,但不能修改现有变量。
  • 无副作用:副作用是状态变化,而不是当前正在执行的功能。修改函数外部定义的变量,打印到控制台,引发异常以及从文件读取数据都是副作用的示例。
  • 无状态:一个函数可能具有内部包含临时状态的局部变量,但是该函数不能引用该函数所属的类或对象的任何成员变量。国家鼓励易变性导致副作用。函数式编程不希望您那样做。

这些是FP的一些关键概念,即规则。即使您始终不遵循所有这些规则,您仍然可以从应用程序中的FP创意中受益。无论如何,C ++绝不是要成为严格或纯函数式编程语言。老实说,函数式编程并不是解决每个问题的正确工具(是的,这是我的观点。将来可能会有所改变。观点会随着经验的变化而改变!)。现在,让我们了解FP擅长解决哪些问题。

用作一流对象

在函数式编程世界中,函数是一流的对象。函数与其他任何变量一样被对待。例如,一个函数可以作为参数传递给其他函数,也可以作为值分配给变量。

1_djs_FQQfX8cw6psDH_hfUw.jpeg

用作一流对象(pinterest.com)

在C ++中,函数不是一流的对象。我们得到的最接近的是lambda表达式。

auto printText = [](std::string text) { std::cout << text << std::endl; };

上面的代码创建了一个lambda printText,它接受一个参数text ,将其输出,但不返回任何内容。该[]支架是用来指定功能关闭。有关lambda的更多信息,请参见此处

通过查看如何应用不同的组合器(如过滤器,映射,C ++向量上的reduce或任何集合),来了解如何实现FP。让我们采用以下向量:

std::vector<std::string> messages = { "Hello Pal", "How are you?", "I'm still coding in C++" };

for_each

std::for_each(messages.begin(), messages.end(), printText);

前两个参数是集合的开始和结束。然后,我们传递的第三个参数是对每个元素进行操作的一元lambda。

让我们创建一个自定义学生对象的向量,并在其上应用组合器。

class Student
{
public:
string _name;
int _score;
Student(string name, int score)
{
_name = name;
_score = score;
}
void incrementScore() {
_score += 1;
}
string name()
{
return _name;
}
int score()
{
return _score;
}
};
std::vector<Student> students = {Student("Alice", 85), Student("Bob", 62), Student("Charlie", 81), Student("Jack", 90), Student("Jimmy", 40), Student("Sherlock", 67),};

假设您是老师,想打印他们的详细信息。然后,您可以使用for_each来打印其详细信息。

auto printStudentDetails = [](Student student) { std::cout << student.name() << " " << student.score() << std::endl; };
std::for_each(students.begin(), students.end(), printStudentDetails);

在上面的代码中,我们使用了打印lambda来打印每个学生的详细信息。

地图

在C ++中,该功能的等效项maptransform。假设,您提出了一个分数不足或无效数据的问题,并想为每个学生加一个分数。然后,您可以使用transform更新每个学生的分数。

auto addOne = [](Student student) { student.incrementScore(); return student; };
std::transform(students.begin(), students.end(), students.begin(), addOne);

您必须提供输入集合的开始,结束指针,输出集合的开始指针和操作。您甚至可以transform一次执行两个集合。您可以检查出来,这超出了本博客的范围。

筛选

在C ++中,该功能filter根据用例具有许多等效项。如果您只想获取具有特定属性的元素的副本,则可以使用copy_if。总之,有喜欢的其他功能remove_iffind_if等过。并且每个这样的函数有一个“ not”候补以及像copy_if_notfind_if_not等等。

auto aboveEighty = [](Student student) { return student.score() > 80; };
vector<Student> topStudents = {};
auto it = std::copy_if(students.begin(), students.end(), back_inserter(topStudents), aboveEighty);
std::for_each(topStudents.begin(), topStudents.end(), printStudentDetails);

的语法为copy_ifcopy_if(Iterator inputBegin, Iterator inputEnd, Iterator outputBegin, predicate)。您必须提供输入集合的开始,结束指针,输出集合的开始指针和操作。我使用了back_inserter_iterator而不是outputBegin,这使我可以将元素推入topStudents向量,而无需初始化向量。

缩小或折叠

reduceC ++中的功能等效项是accumulate。假设您有一个带有数字的向量,并且您想将它们全部求和。

vector<int> numbers{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::cout << std::accumulate(numbers.begin(), numbers.end(), 0,
[](int first, int second) { return first + second; });

您必须提供输入集合的开始,结束指针,累加器的初始值和二进制lambda。累加器也可以应用于我们的自定义学生矢量。下面的代码计算教室的平均分数。

auto binaryOp = [](int score, Student student) { return score + student.score(); };
std::cout << std::accumulate(students.begin(), students.end(), 0, binaryOp)/students.size();

纯函数

在以下情况下,函数是纯函数:

  • 该功能的执行没有副作用。
  • 函数的返回值仅取决于传递给函数的输入参数。
int sum(int a, int b){
return a+b;
}

上面创建的函数是纯函数。许多内置的C ++函数是纯函数,例如min,max,strlen等。您可以编写接受所有const参数且不更改实例变量的函数。在GCC中,您甚至可以使用“ pure”属性将函数标记为纯函数,从而实现更好的优化。如果编译器将某个函数称为纯函数,则可以对其进行循环优化(http://en.wikipedia.org/wiki/Loop_optimization)子表达式消除(http://en.wikipedia.org/wiki/Common_subexpression_elimination)。但是C ++默认情况下也具有副作用,可变性。

public class NonPureFunctionAndMutatingParametersExample{
private int total= 0;

public int add(int nextValue) {
this.total+= nextValue;
return this.total;
}
public void incrementScore(Student &student){
student.score += 1;
}
}

在上面的代码中:

  • 添加方法正在改变状态
  • IncrementScore方法正在更改函数参数

除非必要,否则我们应避免做上述事情。是的,在某些情况下,副作用和可变性会受益。

不可变变量规则是遵循的好习惯。一旦创建了变量并设置了它的值,就可以完全放心地知道该变量的值将永远不会改变,但有时并不适用。如果要构建必须在最终用户配置较低的计算机上运行的应用程序,则内存和时间将有限。在这种情况下,建议接受参数的引用/指针,对其进行更改以节省内存和复制时间。

没有副作用的规则非常有帮助。它使人确信此功能不会影响外界,因此可以在任何地方调用它。但这在某些情况下(例如,写入数据库)会带来困难(这是副作用)。

还有其他一些概念,规则,例如高阶函数,循环递归等,可以在需要时应用。

结论

正如我之前说的,函数式编程是一个了不起的范例,但是在某些情况下,不遵守其中的一些规则可以提供最佳的解决方案。

在过去的几年中,C ++发生了很大的变化。新的构造使其成为构建任何类型的应用程序的绝佳工具。不再只是 带有Class的C了。快乐编码!!!

(原文:https://medium.com/swlh/doing-it-the-functional-way-in-c-5c392bbdd46a)

------------------------

Lambdas:现代C ++的函数式编程伴侣

(原文:Daksh)

由于语法和用法相对较新,因此许多C ++程序员仍然发现编写和使用情况有点困难。

什么是函数式编程

f(x)2 = x * x
f(x,y)2 = x2 + y2 + 2xy
f(x,y)2 = f(x)2 + f(y)2 + f(2xy)
f(x) = x++

为什么要使用函数式编程?


Lambda的语法

[](){};
[](){
cout<<”Hello World”<<endl;
};
[](){
cout<<”Hello World”<<endl;
}(); // See Here.. we're calling by appending()调用
[]() -> int{
cout<<”Hello World”<<endl;
return 1;
}();
int retLambda = []()->int{
cout<<"Hello World"<<endl;
return 1;
}();
int retLambda = [](int value)->int{
cout<<"Hello World"<<endl;
return value + 1;
}(100);
// Getting the function reference using std::function<>
std::function<int(int)> lambdaFn = [](int value)->int{
cout<<"Hello World"<<endl;
return value + 1;
};
// Calling the lambda function here
int retLambda = lambdaFn(100);
auto lambdaFn = [](int value)->int{ 
cout<<"Hello World"<<endl;
return value + 1;
};

f(x)2和创建Lambdaf(x,y)2

std::function<int(int)> fxsquare = [](int x) ->int {
return x * x;
};
int retValue = fxsquare(10);
std::function<int(int, int)> fxsquare = [](int x, int y) ->int {
int xsquare = [](int x) { return x * x; }(x);
int ysquare = [](int y) { return y * y; }(y);
int twoxy = [](int x, int y) { return 2 * x * y;}(x,y);
return xsquare + ysquare + twoxy;
};
int retValue = fxsquare(5,3);

我们在这里编写了一个纯函数式代码

除了功能之外,此代码还有什么好处?

int localvar = 100;
[](){
localvar++; // Compiler error..Not Accessible
}();

lambda的捕获列表[]

int localvar = 100;
int localvar2 = 200;
[localvar](){
cout<<localvar; // Success..
cout<<localvar2; // Compiler Error... can't access
}();
int localvar = 100;
int localvar2 = 200;
[localvar, localvar2](){ ... }
int localvar = 100;
int localvar2 = 200;
[=](){
cout<<localvar; // Success...
cout<<localvar2; // Success...
}();
int localvar = 100;
int localvar2 = 200;
[=](){
localvar++; // Compiler Error
localvar2++; // Compiler Error
}();
int localvar = 100;
int localvar2 = 200;
[&](){
localvar++; // Success...
localvar2++; // Success...
}();

为创建Lambda f(x,y)2 using Capture List

int x = 5, y = 3;
std::function<int(void)> fxsquare = [x,y]() ->int {
int xsquare = [](int x) { return x * x; }(x);
int ysquare = [](int y) { return y * y; }(y);
int twoxy = [](int x, int y) { return 2 * x * y;}(x,y);
return xsquare + ysquare + twoxy;
};
int retValue = fxsquare();

在班级内使用捕获列表

template<int iValue, int jValue>
struct AbcTest {
int i = iValue;
int j = jValue;
int sumFn() {
return [this](){
return this->i + this->j;
}();
}
};
// Using class
AbcTest<100,200> aTest;
int sum = aTest.sumFn()
【版权声明】本文为华为云社区用户翻译文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容, 举报邮箱:cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。