使用auto对C++局部变量进行初始化

一、局部变量

思想:使用auto初始化变量,具体类型后置

#include <cstdint>
#include <cstring>
#include <iostream>
#include <type_traits>

using namespace std;
int main(int argc, char **argv) {
    
    
	//不好的做法:
	int i1;

	//好的做法
	//原始做法
  int i = 0;
  cerr << i << endl;

  // 使用auto
  auto j = 0;//auto j =int();
  cerr << j << endl;

  auto z = [&]() {
    
    
    for (int i = 0; i < argc; ++i) {
    
    
      if (!strcmp(argv[i], "-h"))
        return i;
    }
    return -1;
  }();
  cerr << z << endl;

  return 0;
}
#include <chrono>
#include <cstdint>
#include <cstring>
#include <iostream>
#include <memory>
#include <type_traits>
#include <vector>
#include <chrono>

using namespace std;

struct C {
    
    
  int a;
  int b;
};

using namespace std::literals;
int main(int argc, char **argv) {
    
    
  // 好的做法
  auto s1 = std::string("hello");

  // 好的做法
  auto s2 = "hello"s;
  1s;

  return 0;
}

二、结构体变量初始化

#include <cstdint>
#include <cstring>
#include <iostream>
#include <memory>
#include <type_traits>

using namespace std;

struct C {
    
    
  int a;
  int b;
};

int main(int argc, char **argv) {
    
    
  auto c = C{
    
    };

  cerr << c.a << endl;

  // 不好的做法:
  auto p_c = new C;
  //   好的做法:
  // make_unique会调用默认构造函数
  auto n_c = std::make_unique<C>();

  return 0;
}
#include <cstdint>
#include <cstring>
#include <iostream>
#include <memory>
#include <type_traits>

using namespace std;

struct C {
    
    
  // 避免写多余的构造函数
  int a = 1;
  std::string b = "wangji"s;
};

int main(int argc, char **argv) {
    
    
  // 好的做法
  auto c = C{
    
    1, "w"};

  // 好的做法,为struct C中新增成员,不影响这里的初始化
  auto b = C{
    
    .a = 100};

  cerr << c.a << endl;

  return 0;
}

三、for循环中可能存在的隐式类型转换:

#include <cstdint>
#include <cstring>
#include <iostream>
#include <memory>
#include <type_traits>
#include <vector>

using namespace std;

struct C {
    
    
  int a;
  int b;
};

int main(int argc, char **argv) {
    
    
  auto a = std::vector<char>(0x1ffffff);

  // 可能存在的隐式类型转换
  size_t i = 0;
  // 不存在隐式类型转换,auto i = (size_t)0;
  auto i = size_t(0);

  //不好的做法: i会被推到成int类型,
  // a.size()是std::size_t类型,i < a.size()可能会造成代码死循环
  for (auto i = 0; i < a.size(); ++i) {
    
    

    cerr << a[i];
  }
  // 好的做法:
  for (auto i = size_t(0); i < a.size(); ++i) {
    
    
    cerr << a[i];
  }

  // 好的做法:static_cast<size_t>(0):防止C风格的强转:int*p;static_cast<size_t>(p)
  // C风格强转:int*p;size_t(p) 或者reinterpret_cast<size_t>(p)
  for (auto i = static_cast<size_t>(0); i < a.size(); ++i) {
    
    
    cerr << a[i];
  }

  return 0;
}

四、函数

#include <cstdint>
#include <cstring>
#include <iostream>
#include <memory>
#include <type_traits>

using namespace std;

// 不好的做法,防止函数修改参数,导致调用处的函数工作异常
float lerp(float from, float to, float fac) {
    
     return fac * (to - from) + from; }

// 好的做法
struct Lerp {
    
    
  float from;
  float to;
  float fac;

  float operator()() const {
    
     return fac * (to - from) + from; }
};

// 好的做法
struct LerpWithResult {
    
    
  float from;
  float to;
  float fac;

  struct Result {
    
    
    float value;
    float secondvalue;
  };

  Result operator()() const {
    
    

    return {
    
    .value = fac * (to - from) + from,
            .secondvalue = fac * (from - to) + to};
  }
};

int main(int argc, char **argv) {
    
    

  auto x = lerp(1, 2, 0.2);
  cout << x << endl;

  // 好处:更好看,给那个参数赋值了
  auto y = Lerp{
    
    .from = 1, .to = 2, .fac = 0.2}();
  cout << y << endl;
  ;

  auto [u, v] = LerpWithResult{
    
    .from = 1, .to = 2, .fac = 0.2}();
  cout << u;

  return 0;
}

参考:

猜你喜欢

转载自blog.csdn.net/u011436427/article/details/131099532