美文网首页
现代c++笔记(3)

现代c++笔记(3)

作者: Teech | 来源:发表于2021-06-20 23:15 被阅读0次
    • Alias Template
    template <typename T>
    using Vec = std::vector<T, MyAlloc<T>>
    Vec<int> coll;
    //define也无法达到相同的效果
    //typedef 不能接受参数
    //不能对偏特化或者全特化起作用
    
    //打算实现这样
    //想萃取test_move(vector<MyString>())中的MyString
    typdef typename iterator_traits<typename Container::iterator>::value_type ValType;
    
    • temlate temlate parrameter
    //template<typename T, template<typename U> class Container> //写法1  
    template<typename T, template<class> class Container>       //写法2
    class XCls {
    private:
        Container<T> c;
    public:
        // ...
    };
    
    • type alias
    //第一种用法
    //typedef void (*fun)();    //传统写法
    using func = void(*)(); //新标准写法
    void example(){}
    fun f = example;
    //第二种用法
    template<typename T>
    struct MyContiner
    {
        using mytype = T;//typedef T mytype 
    };
    //第三种用法 alias tmplelate
    template<typename charT>
    using myString = std::basic_string<charT, std::char_traits<charT>>;
    myString<char> str;
    //传统写法typedef不能用于模版
    typedef std::basic_string<char, std::char_traits<char>> myString2;
    myString2 str2;
    
    • using 作用
    //导入命名空间
    using namespace std;
    using std::cout;
    //在class种使用using
    protected:
        using _Basic::_M_alloc;
    //type-alias 以及alias template(c++ 11以后)
    
    • noexcept
    //异常如果一直没处理,会一直往调用链往上传递,如果都没处理,最终程序会执行std::abort() 终止程序
    //定义一个函数 保证不抛出异常
    void foo() noexcept;//void foo() noexcept(true);
    //定义一个函数不抛出异常,条件是x.swap(y)不抛出异常
    void swap(Type& x,Type& y) noexcept(noexcept(x.swap(y))
    {
      x.swap(y);
    }
    //你需要通知c++(特别是vector),你的移动构造以及赋值构造不会抛出异常也就是noexcept,Then,move构造函数才会被调用当vector扩容时,如果没有申明noecept,那么std::vector不能使用它
    //https://stackoverflow.com/questions/8001823/how-to-enforce-move-semantics-when-a-vector-grows                                    
    class MyString {
    private:
        char* _data;
        size_t len;
    public:
        //move constructor
        MyString(MyString&&str) noexcept
            :_data(str._data),len(str.len){
        }
        MyString& operator=(MyString&& str) noexcept
        {
            _data = str._data;
            len = str.len;
            str._data = nullptr;
            return *this;
        }
    };
    
    //std::vector<MyString>不停push_back当发生扩容的时候,到底使用拷贝构造函数还是移动构造函数看MyString种移动构造函数到底有没有申明noexcept 
    //正常情况下,移动构造以及移动赋值都要申明成noexcept,这样不论使用的容器时申明都会比较安心  
    
    • Override
    class base {
        virtual void fun(float a){}
    };
    class derived :base {
        //这么写会导致新的函数申明
        //virtual void fun(int a) {}
        //override帮助编译器,如果函数原型不一致会导致编译出错
        virtual void fun(int a) override {}
    };
    
    • Final
    //修饰class表示不能被继承,我是最后一个
    class base1 final {
    };
    class derived :base1 {}
    };
    //修饰虚函数表示不能被override 否则编译出错
    class base2 {
        virtual void fun() final {} 
    };
    class devived :base2
    {
        virtual void fun() {}
    };
    
    • Decltype
    std::map<int, float> coll;
    decltype(coll)::value_type elem;//11之前只能std::map<int, float>::value_type elem
    //1.申明返回类型,c++11之前
    //打算这么写 但是编译不过 x + y在之前出现
    template<typename T1,typename T2>
    decltype(x + y) add(T1 x,T2 y);
    //所以这么写
    //很像lambda
    template<typename T1,typename T2>
    auto add(T1 x,T2 y) ->decltype(x + y);//auto + -> 指明返回类型
    //2.metaprograming 模板
    template <typename T>
    void test(T obj){
      typedef typename decltype(obj)::iterator iType;
      //typedef typename T::iterator iType;
    }
    //3.获取lambda的类型
    auto cmp = [](const P& p1,const P& p2){
      return p1.lastname() < p2.lastname();
    }
    std::set<P,decltype(cmp)> col(cmp);
    
    • lambda
    lambda是个inline 函数或者可以理解临时对象
      auto l = [] {
      std::cout << 11;
        };
        l(); 
    //完整形式
    [...](...) mutable(opt) throwSpec(opt) -> retType(opt){...}
    [...]:导入器
    (...):参数
    retType:返回类型
    {...}:函数本体
    //例子:
    int x = 0;
    int y = 1;
    auto q = [x,&y]{...};//&修饰为传递引用的方式 x为传值的方式
    auto q = [=,&y]{...};//=号表示其他外部区域以传值的方式传递
    
    //例子:
        int id = 0;
        //如果不加mutable ++id不能编译通过 如果传递引用的方式过来就可以
        auto f = [id]()mutable {
            std::cout << id << std::endl;
            ++id;
        };
        id = 42;
        f();
        f();
        std::cout << id << std::endl;
    //主要id是传值的方式传递过去的
    >out: 0 1 42
    lambda相当于匿名的函数对象
    class Functor {
    private:
        int id;
    public:
        void operator()() {
            std::cout << id << std::endl;
        }
    };
    

    相关文章

      网友评论

          本文标题:现代c++笔记(3)

          本文链接:https://www.haomeiwen.com/subject/ogreyltx.html