可变参数与foreach 的原理

曾经写过c++11特性使用,但是这个究竟是什么呢,和其他语言的foreach语句十分相像

函数必须具有在编译时已知的单个返回类型;当编译器可以从上下文中找出它必须是什么时,auto只会使您不必输入它。所以你给一个模版类,如果编译的时候没有其类型,一定是无法通过的,我们使用map其实是在调用这个库的代码,当然map本身是无法编译和运行,其必须要KeyValue类型参数。

当然C++14的auto和11的不一样,在那篇文章仅是介绍了auto的使用,我们是无法看出之间的区别的,我们实现一个函数把vector所有元素*3并返回

//C++98
std::vector<int> &multiply_by_three(std::vector<int> &v)
{
    for (std::vector<int>::iterator it = v.begin(); it != v.end(); it++)
    {
        *it *= 3;
    }
    return v;
}

初学者还很容易忘记iterator怎么拼,有时候也会写错

//C++11
std::vector<int> &multiply_by_three(std::vector<int> &v)
{
    //这里&表示引用,而不是求地址运算符,是可以直接操作的,用来加快速度
    //(指针和引用都不会创建新的对象。构造对象和析构对象的开销可能是庞大的)
    for (auto &it : v)
    {
        it *= 3;
    }
    return v;
}

更快,更好写

auto& multiply_by_three(std::vector<int>& v)
{
      for(auto& it : v)
      {
          it *= 3;
      }
      return v;
}

支持返回值的类型判断,我们有时候也会写匿名函数,比如sort这样的

 sort(S.begin(),S.end(),[]
    (const string &s,const string &c)
    {
      return s>c;
    }
    );

其实这都属于语法糖Lambda

下面是各种变量截取的选项:

  • [] 不截取任何变量
  • [&} 截取外部作用域中所有变量,并作为引用在函数体中使用
  • [=] 截取外部作用域中所有变量,并拷贝一份在函数体中使用
  • [=, &foo]   截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用
  • [bar]   截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量
  • [this]            截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。

语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的字节码或者特定的方式对这些语法做一些处理,开发者就可以直接方便地使用了。这种语法对语言本身功能来说没有什么影响,只是为了方便程序员的开发,提高开发效率。说白了,语法糖就是对现有语法的一个封装。这些语法糖虽然不会提供实质性的功能改进,但是它们或能提高性能、或能提升语法的严谨性、或能减少编码出错的机会。

我们可以看他的遍历的汇编代码有什么不同

用的是-S命令,比如gcc -g -S B.cpp

我没对比出什么啊,有些指令不一样,但是我也不是看得太懂

原文地址:https://www.cnblogs.com/BobHuang/p/11220700.html

时间: 2024-10-17 22:54:22

可变参数与foreach 的原理的相关文章

Java语法糖1:可变长度参数以及foreach循环原理

语法糖 接下来几篇文章要开启一个Java语法糖系列,所以首先讲讲什么是语法糖.语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的字节码或者特定的方式对这些语法做一些处理,开发者就可以直接方便地使用了.这些语法糖虽然不会提供实质性的功能改进,但是它们或能提高性能.或能提升语法的严谨性.或能减少编码出错的机会.Java提供给了用户大量的语法糖,比如泛型.自动装箱.自动拆箱.foreach循环.变长参数.内部类.枚举类.断言(as

c 可变参数(variable argument)的原理及使用

本文主要介绍可变参数的函数使用,然后分析它的原理,程序员自己如何对它们实现和封装,最后是可能会出现的问题和避免措施. VA函数(variable argument function),参数个数可变函数,又称可变参数函数.C/C++编程中,系统提供给编程人员的va函数很少.*printf()/*scanf()系列函数,用于输入输出时格式化字符串:exec*()系列函数,用于在程序中执行外部文件(main(int argc,char*argv[]算不算呢,与其说main()也是一个可变参数函数,倒不

Java中的可变参数以及foreach语句

Java中的可变参数的定义格式如下: 返回值类型  方法名称(类型 ... 参数名称){} foreach语句的格式如下: for ( 数据类型  变量名称 :数据名称){ ... } public class NewDemo01 { public static void main(String[] args) { // TODO Auto-generated method stub fun(); fun(1); fun(1,2,3,4); } public static void fun(in

C++可变参数的另一种实现

大家熟知的C库函数printf函数就是一个可变参数函数,它是怎么实现的呢?不过他实现是有条件的,必须函数参数的入栈顺序为从右向左的顺序,也即函数的形参,在函数调用之前,必须是最右边的参数先入栈,并且参数都必须通过栈传递,以1个例子说明,如函数func(arg1, arg2,arg3),那么函数的堆栈应是: ebp是帧指针寄存器,一般用来存取堆栈,有了堆栈结构,下面我们看看C可变参数的具体实现原理: [html] view plain copy #include <stdio.h> enum {

C语言——可变参数

http://blog.chinaunix.net/space.php?uid=25304914&do=blog&id=3066441 一.是什么 我们学习C语言时最经常使用printf()函数,但我们很少了解其原型.其实printf()的参数就是可变参数,想想看,我们可以利用它打印出各种类型的数据.下面我们来看看它的原型: int printf( const char* format, ...); 它的第一个参数是format,属于固定参数,后面跟的参数的个数和类型都是可变的(用三个点&

C语言可变参数

转自http://www.cnblogs.com/wangyonghui/archive/2010/07/12/1776068.html,稍有改动 一.是什么 我们学习C语言时最经常使用printf()函数,但我们很少了解其原型.其实printf()的参数就是可变参数,想想看,我们可以利用它打印出各种类型的数据.下面我们来看看它的原型: int printf( const char* format, ...); 它的第一个参数是format,属于固定参数,后面跟的参数的个数和类型都是可变的(用三

C语言可变参数函数实现原理

一.可变参数函数实现原理 C函数调用的栈结构: 可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈. 本文地址:http://www.cnblogs.com/archimedes/p/variable-parameter.html,转载请注明源地址. 例如,对于函数: void fun(int a, int b, int c) { int d; ... } 其栈结构为 0x1ffc-->d 0x200

JAVA笔记4__static关键字/对象数组/foreach/方法的可变参数

/** * static关键字:修饰属性(实质就是全局变量).方法(无需本类的对象即可调用此方法).类. * 1.static方法只能调用static方法 * 2.static方法只能访问static数据 * 3.static方法不能以任何方式引用this或super */ public class Main { public static void main(String[] args) { A a = new A(); a.val = 2; A a1 = new A(); a1.val =

C利用可变参数列表统计一组数的平均值,利用函数形式参数栈原理实现指针运算

//描述:利用可变参数列表统计一组数的平均值 #include <stdarg.h> #include <stdio.h> float average(int num, ...);//函数原型:即声明 float average2(int num, ...);//num个数 void add(int num, int x, int y, int z); int main(void){ int a=10; int b=20; printf("a地址:%p b地址:%p\n&