FX-C++11-auto自动推导类型

在C++11中,auto 关键字被引入用于自动类型推断。它允许编译器根据初始化表达式自动推断变量的类型,从而简化代码并提高可读性。以下是一些关于 auto 的复习要点:

1. 基本用法

auto 关键字用于声明变量时,编译器会根据初始化表达式的类型自动推断变量的类型。

auto x = 42;        // x 的类型被推断为 int
auto y = 3.14;      // y 的类型被推断为 double
auto z = "Hello";   // z 的类型被推断为 const char*
auto nb;            // error,变量必须要初始化
auto double nbl;    // 语法错误, 不能修改数据类型

当变量不是指针或者引用类型时,推导的结果中不会保留const、volatile关键字
当变量是指针或者引用类型时,推导的结果中会保留const、volatile关键字

int temp = 110;
auto *a = &temp;	
auto b = &temp;		
auto &c = temp;		
auto d = temp;		
//变量a的数据类型为 int*,因此auto关键字被推导为 int类型
//变量b的数据类型为 int*,因此auto关键字被推导为 int*类型
//变量c的数据类型为 int&,因此auto关键字被推导为 int类型
//变量d的数据类型为 int,因此auto关键字被推导为 int类型

2. 与复杂类型一起使用

auto 在处理复杂类型时特别有用,尤其是在模板编程和迭代器中。

std::vector<int> vec = {1, 2, 3, 4, 5};
for (auto it = vec.begin(); it != vec.end(); ++it) {
    // it 的类型被推断为 std::vector<int>::iterator
    std::cout << *it << std::endl;
}

3. 与 const 和引用一起使用

auto 可以与 const 和引用结合使用,但需要注意推断规则。

const auto a = 10;       // a 的类型被推断为 const int
auto& b = a;             // b 的类型被推断为 const int&
auto c = b;              // c 的类型被推断为 int(去掉了 const 和引用)

int tmp = 250;
const auto a1 = tmp;
auto a2 = a1;
const auto &a3 = tmp;
auto &a4 = a3;
//变量a1的数据类型为 const int,因此auto关键字被推导为 int类型
//变量a2的数据类型为 int,但是a2没有声明为指针或引用因此 const属性被去掉, auto被推导为 int
//变量a3的数据类型为 const int&,a3被声明为引用因此 const属性被保留,auto关键字被推导为 int类型
//变量a4的数据类型为 const int&,a4被声明为引用因此 const属性被保留,auto关键字被推导为 const int类型

4. auto 与函数返回类型

C++14 引入了 auto 作为函数返回类型的推断,但在 C++11 中,auto 只能用于尾随返回类型。

// C++11
auto add(int a, int b) -> int {
    return a + b;
}

// C++14
auto add(int a, int b) {
    return a + b;
}

5. auto 与 decltype

decltype 可以与 auto 一起使用,用于推断表达式的类型。

int x = 10;
decltype(x) y = 20;  // y 的类型被推断为 int

6. auto 的限制

  • auto 不能用于函数参数(C++20 引入了 auto 作为函数参数类型)。

  • auto 不能用于非静态成员变量。

  • auto 不能用于数组类型。

auto关键字并不是万能的,在以下这些场景中是不能完成类型推导的:

  • 不能作为函数参数使用。因为只有在函数调用的时候才会给函数参数传递实参,auto要求必须要给修饰的变量赋值,因此二者矛盾。
int func(auto a, auto b)    // error
{    
    cout << "a: " << a <<", b: " << b << endl;
}
  • 不能用于类的非静态成员变量的初始化
class Test
{
    auto v1 = 0;                    // error
    static auto v2 = 0;             // error,类的静态非常量成员不允许在类内部直接初始化
    static const auto v3 = 10;      // ok
}
  • 不能使用auto关键字定义数组
int func()
{
    int array[] = {1,2,3,4,5};  // 定义数组
    auto t1 = array;            // ok, t1被推导为 int* 类型
    auto t2[] = array;          // error, auto无法定义数组
    auto t3[] = {1,2,3,4,5};;   // error, auto无法定义数组
}
  • 无法使用auto推导出模板参数
template <typename T>
struct Test{}

int func()
{
    Test<double> t;
    Test<auto> t1 = t;           // error, 无法推导出模板类型
    return 0;
}

7. auto 与初始化列表

auto 与初始化列表一起使用时,推断的类型是 std::initializer_list

auto list = {1, 2, 3};  // list 的类型被推断为 std::initializer_list<int>

8. auto 与 lambda 表达式

auto 可以用于存储 lambda 表达式。

auto lambda = [](int x) { return x * x; };
int result = lambda(5);  // result 的值为 25

9. auto 与模板

auto 在模板编程中非常有用,可以简化代码并减少模板参数的使用。

template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
    return t + u;
}
#include <iostream>
#include <string>
using namespace std;

class T1
{
public:
    static int get()
    {
        return 10;
    }
};

class T2
{
public:
    static string get()
    {
        return "hello, world";
    }
};

template <class A>
void func(void)
{
    auto val = A::get();
    cout << "val: " << val << endl;
}

int main()
{
    func<T1>();
    func<T2>();
    return 0;
}

 在这个例子中定义了泛型函数func,在函数中调用了类A的静态方法 get() ,这个函数的返回值是不能确定的,如果不使用auto,就需要再定义一个模板参数,并且在外部调用时手动指定get的返回值类型,具体代码如下:

#include <iostream>
#include <string>
using namespace std;

class T1
{
public:
    static int get()
    {
        return 0;
    }
};

class T2
{
public:
    static string get()
    {
        return "hello, world";
    }
};

template <class A, typename B>        // 添加了模板参数 B
void func(void)
{
    B val = A::get();
    cout << "val: " << val << endl;
}

int main()
{
    func<T1, int>();                  // 手动指定返回值类型 -> int
    func<T2, string>();               // 手动指定返回值类型 -> string
    return 0;
}

10. auto 与范围 for 循环

auto 常用于范围 for 循环中,简化迭代代码。

std::vector<int> vec = {1, 2, 3, 4, 5};
for (auto& elem : vec) {
    elem *= 2;  // elem 的类型被推断为 int&
}

总结

auto 是 C++11 引入的一个强大特性,它简化了代码并提高了可读性,特别是在处理复杂类型和模板编程时。然而,使用时需要注意类型推断的规则,以避免潜在的错误。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值