C++开发二三事(一)

    xiaoxiao2025-05-22  38

    C++开发二三事(一)

    学会阅读英文官方docoptional对象的默认转化c++ lambda 表达式find和[]的区别numeric_limits 最近开始接触linux下的c++开发,在此记录开发过程中遇到的问题以及学习到的新特性。本文并不会详细阐述,只是记录走过的坑和tricks.

    学会阅读英文官方doc

    目前关于c++比较权威和官方的api文档可以参考CPP Reference,多阅读官方介绍可以少走很多坑和理解很多特性和设计。

    optional对象的默认转化

    boost和c++14提供了optional用于表示一个对象的未初始化状态,可以用作返回值或者参数传入,optional提供了统一的none代表未初始化状态,避免了使用magic value。std::optional<T> 可以和类型T一样进行赋值,例如:

    #include <optional> std::optional<int> opt_a = 10 ; opt_a = 5 ; //change opt_a to 5 ;

    同样,如果你使用optional作为函数传入对象,也可以直接使用对应的对象直接调用函数,但注意,这样会调用拷贝构造函数!即进行深拷贝,上面代码段中的赋值操作也调用了拷贝构造函数。例如下述代码段:

    #include <iostream> #include <optional> class MyInt{ public: int v ; int getv(){return v;} MyInt(int pv) { std::cout << "Constructor Called" << std::endl; v = pv;} MyInt(const MyInt& mi){ std::cout << "Copy Constructor Called" << std::endl; v = mi.v; } }; void funca(std::optional<MyInt> p){ std::cout << "funca call " << p->v << std::endl ; } int main() { MyInt a(5) ; funca(a) ; //auto Myint to optional<Myint>, Copy Constructor called. funca(5) ; //auto construct, constructor called return 0; }

    此外optional还支持直接构造,实现类似emplace_back的功能,避免额外构造一遍 上述代码的输出将会是:

    Constructor Called Copy Constructor Called funca call 5 Constructor Called funca call 5

    同时std::optional中的type T必须是value type,即不支持引用类型,个人理解是你如果使用引用,代表该值不能为空,所以不提供这一操作。

    c++ lambda 表达式

    c++ 也提供lambda表达式用于书写简介的代码段来完成重复的功能,或作为sort等函数的传入参数,使用非常方便。关于lambda表达式的使用有很多资料,在此只提醒两点

    在进行外部捕获变量时显式指定,而不是默认全局捕获,这样可以提高代码的可读性(readbility),同时也避免别人在作用域添加了别的变量产生不必要的捕获lambda表达式应尽量简洁,在数行或者一个循环内完成,否则应定义单独的function,这也是为了提高可读性(readbility)

    find和[]的区别

    c++中的map和unordered_map提供了[]和find两种方法来进行查询操作,这两者实际上是有区别的。使用[]进行查询时如果key不存在,则会插入key,而对应的value则会使用默认的构造函数进行构造。e.g.

    std::unordered_map<string, string> dict ; std::string name = dict["lost"] ; //name will be "" mostly, but not sure...

    使用find时我们可以通过dict.find("key") != dict.end()判断key是否存在。 进一步的,find操作不会修改map的数据,是const的;相反,[] operator 则有可能修改,是非const的。由于[] operator的行为并不可控,且会自动插入数据,使用find是更安全的。关于[] operator 详细的介绍参考C++ Reference

    numeric_limits

    numeric_limits 是c++ 标准库提供的数值类型的最大最小的值及其他特性介绍,可用于避免溢出(overfloat) 和用作初始值以及一些判定。提供了int, long, long long 等类型,详细参考CPP Reference

    // numeric_limits example #include <iostream> // std::cout #include <limits> // std::numeric_limits int main () { std::cout << std::boolalpha; std::cout << "Minimum value for int: " << std::numeric_limits<int>::min() << '\n'; std::cout << "Maximum value for int: " << std::numeric_limits<int>::max() << '\n'; std::cout << "int is signed: " << std::numeric_limits<int>::is_signed << '\n'; std::cout << "Non-sign bits in int: " << std::numeric_limits<int>::digits << '\n'; std::cout << "int has infinity: " << std::numeric_limits<int>::has_infinity << '\n'; return 0; }
    最新回复(0)