【学习日志】2022.11.07 格林公式、C++11(decltype、追踪返回、使用列表初始化防止类型收窄)

格林公式

 


C++11

auto错误示例

void fun(auto x =1) {}  // 1: auto函数参数,有些编译器无法通过编译

struct str
{
    auto var = 10;   // 2: auto非静态成员变量,无法通过编译
};

int main()
{
    char x[3];
    auto y = x;
    auto z[3] = x; // 3: auto数组,无法通过编译

    // 4: auto模板参数(实例化时),无法通过编译
    vector<auto> x = {1};

    return 0;
}

decltype

#include <typeinfo>
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    int i;
    decltype(i) j = 0;
    cout << typeid(j).name() << endl;   // 打印出"i", g++表示integer

    float a;
    double b;
    decltype(a + b) c;
    cout << typeid(c).name() << endl;   // 打印出"d", g++表示double

    vector<int> vec;
    typedef decltype(vec.begin()) vectype; // decltype(vec.begin()) 改名为 vectype

    vectype k;  
    //decltype(vec.begin()) k;  
    for (k = vec.begin(); k < vec.end(); k++)
    {
        // 做一些事情
    }

    enum {Ok, Error, Warning}flag;   // 匿名的枚举变量
    decltype(flag) tmp = Ok;

    return 0;
}

追踪返回


int func(int, int);
auto func2(int, int) -> int;

template<typename T1, typename T2>
auto sum(const T1 & t1, const T2 & t2) -> decltype(t1 + t2)
{
    return t1 + t2;
}

template <typename T1, typename T2>
auto mul(const T1 & t1, const T2 & t2) -> decltype(t1 * t2)
{
    return t1 * t2;
}

int main()
{
    auto a = 3;
    auto b = 4L;
    auto pi = 3.14;

    auto c = mul( sum(a, b), pi );
    cout << c << endl;  // 21.98

    return 0;
}

类中成员变量直接初始化

class Mem
{
public:
    Mem(int i): m(i){} //初始化列表给m初始化
    int m;
};
class Group
{
public:
    Group(){}

private:
    int data = 1;   	// 使用"="初始化非静态普通成员,也可以 int data{1};
    Mem mem{2};	// 对象成员,创建对象时,可以使用{}来调用构造函数
    string name{"mike"};
};

列表初始化

int a[]{1, 3, 5};
int i = {1};  
int j{3}; 

初始化列表可以用于初始化结构体类型,例如:

struct Person  
{  
  std::string name;  
  int age;  
};  
  
int main()  
{  
    Person p = {"Frank", 25};  
    std::cout << p.name << " : " << p.age << std::endl;  
}  

其他一些不方便初始化的地方使用,比如std<vector>的初始化,如果不使用这种方式,只能用构造函数来初始化,难以达到效果:

std::vector<int> ivec1(3, 5);  
std::vector<int> ivec2 = {5, 5, 5};  
std::vector<int> ivec3 = {1,2,3,4,5}; //不使用列表初始化用构造函数难以实现  

使用列表初始化防止类型收窄

类型收窄指的是导致数据内容发生变化或者精度丢失的隐式类型转换,使用列表初始化可以防止类型收窄。

int main(void)
{
    const int x = 1024;
    const int y = 10;

    char a = x;                 // 收窄,但可以通过编译
    char* b = new char(1024);   // 收窄,但可以通过编译

    char c = { x };             // err, 收窄,无法通过编译
    char d = { y };             // 可以通过编译
    unsigned char e{ -1 };      // err,收窄,无法通过编译

    float f{ 7 };               // 可以通过编译
    int g{ 2.0f };              // err,收窄,无法通过编译
    float * h = new float{ 1e48 };  // err,收窄,无法通过编译
    float i = 1.2l;                 // 可以通过编译

    return 0;
}

扫描二维码关注公众号,回复: 14752571 查看本文章

猜你喜欢

转载自blog.csdn.net/Angelloveyatou/article/details/127728002
今日推荐