您的位置:首页 > 编程语言 > C语言/C++

C++11之动态类型引入(影响面广)

2017-01-05 07:36 232 查看
python、perl等语言中的“动态类型”功能让C++程序员很羡慕,也即变量不需要声明类型,拿来就用,类型是在运行中实时确定的。C++98标准中只有“静态类型”,定义的变量在编译期间就要确定类型,C++11标准将以前很少用的atuo(C++98中为自动存储类型,所有的局部变量默认都为这种类型)原功能取消,赋予了新的功能:“动态类型”。

一、C++11中的auto功能:

1.1、通过推导可以接收任何类型,包括自定义类型。示例如下:

#include <iostream>

using namespace std;

class A

{

    public:

        A(int i=0):m_ia(i){};

        void Show(void) { cout << m_ia << endl;}

    private:

        int m_ia;

};

int main()

{

    // 基本类型

    double d(0);

    auto ad = d;

    cout << ad << endl;

 // 自定义类型

    A ao;

    auto aao = ao;

    aao.Show();

    return 1;
}

1.2、使STL编程更加简洁清晰

STL编码中经常使用到容器,如果加上名字空间,会变得非常长。如下述代码:

#include <iostream>

#include <vector>

int main()

{

std::vector<std::string> vs;

vs.push_back("I am a student");
vs.push_back("hello world!");

for(std::vector<std::string>::iterator it=vs.begin(); it<vs.end(); it++)

{

cout << *it << endl;

}

}

换成auto,循环语句for则可变为:

for(auto it=vs.begin(); it<vs.end(); it++)

1.3、推导未知类型(自适应性):
存在这样一种情况,某个模块的返回值我们不知道其确切的类型, 如下一个模板函数:

template<typename T1, typename T2>

T1 cal(T1 t1, T2 t2)

{

    return (t2-t1);

}

int main()

{

int rt = cal(1, 2.1);

cout << rt << endl;

rt = cal(2.1, 1);

    cout << rt << endl;

}

结果为1和-1。如下改为auto

int main()

{

auto rt1 = cal(1, 2.1);

cout << rt1 << endl;

auto rt2 = cal(2.1, 1);

    cout << rt2 << endl;

}

结果为1和-1.1。细心的读者会发现为什么要定义两个auto型变量,如果只定义一个auto变量,该变量在运行时会被明确一个类型,第二处调用返回的类型将被强制转化为明确的类型。

二、与python、perl中的“动态类型”区别:

2.1、声明形式不同:

python、perl中任意一个标识符就是一个变量名,这种随意性其实并不严格,让人感觉到语法混乱,而C++11中则必须声明为auto型,保持了原有的习惯。

三、注意事项:

3.1、auto声明的变量必须初始化,否则编译报错,这也是合情合理,符合用即申请,不用不申请的原则。

auto a; 

a = 1;

以上代码编译会报错!必须改为:

auto a = 1;

3.2、不能自动扩展。

unsigned int x = 4294967295;

unsigned int y = 1;

auto c = x+y;

c的值会变为0。

3.3、与指针及引用结合使用。auto和auto *没有什么区别,如果是引用,则必须用auto &。用const修饰不具有传递性。如:

int i;

const auto a = i; // 推导为const int

auto b = a;         // 推导为int,const不具备传递性

3.4、在同一语句中用auto声明多个变量时,只有第一个变量用于类型推导,后面都是同样的类型,如下则会出现编译报错。

auto x=1, y = 2.1;

auto x=2.1, y=1;  // 同样也错,不要认为可以隐式转换!

3.5、auto可以使用初始化表和new动态分配内存,如下代码:

auto a{1};

auto a = new auto{1};

3.6、auto不可以做为函数参数

void f(auto a = 1){} // 编译报错!

3.7、对于类与结构体来说,只有const static类型的auto成员变量才是合法的

class A

{

const static auto i = 20; // 正确

        const auto i = 20;            // 报错

        static auto i = 20;            // 报错



3.8、auto变量可以接收数组,如下代码是正确的:

int main()

{

    int a[3] = {0};

    auto aa = a;

//  auto aaa[3] = a;    // 错误!

    for(int i=0; i<3; i++)

        cout << aa[i] ;

 

    return 1;

}

结果为:000 

3.9、模板参数实例化时不能使用auto作为参数类型,如下代码无法编译:

stack<auto> s = {100};

3.10、注意关于auto语义混乱,在C99和C++98中:auto int a = 100;是正确的,在C++11中则是错误!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: