zoukankan      html  css  js  c++  java
  • STL中常用的c++语法

    函数调用操作(c++语法中的左右小括号)可以被重载,STL的特殊版本都以仿函数形式呈现。如果对某个class进行operator()重载,它就成为一个仿函数。

    仿函数(functor),就是使一个类的使用看上去象一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了

    #include <iostream>
    using namespace std;
    
    template<class T>
    struct Plus
    {
        T operator()(const T& x, const T& y)const
        {
            return x + y;
        }
    };
    
    template<class T>
    struct Minus
    {
        T operator()(const T& x, const T& y)const
        {
            return x - y;
        }
    };
    
    int main()
    {
        Plus<int>plusobj;
        Minus<int>minusobj;
    
        cout << plusobj(3, 4) << endl;
        cout << minusobj(3, 4) << endl;
    
        //以下直接产生仿函数的临时对象,并调用
        cout << Plus<int>()(43, 50) << endl;
        cout << Minus<int>()(43, 50) << endl;
    
        system("pause");
        return 0;
    }

    产生临时对象的方法:在类型名称后直接加一对小括号,并可指定初值

    vector<int>() = {1};

    。stl常将此技巧应用于仿函数与算法的搭配上。

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    /*
    template <class InputIterator,class Function>
    Function for_each(InputIterator first, InputIterator last, Function f)
    {
        for (; first != last; ++first)
        {
            f(*first);
        }
        return f;
    }
    */
    
    template <typename T>
    class print
    {
    public:
        void operator()(const T& elem)
        {
            cout << elem << ' ' << endl;
        }
    };
    
    int main()
    {
        int ia[6] = { 0,1,2,3,4,5 };
        vector<int>iv(ia, ia + 6);
    
        for_each(iv.begin(), iv.end(), print<int>());
    
        system("pause");
        return 0;
    }

    静态常量整数成员在class内部直接初始化,否则会出现链接错误

    In C++11, non-static data members, static constexpr data members, and static const data members of integral or enumeration type may be initialized in the class declaration. e.g.

    struct X {
        int i=5;
        const float f=3.12f;
        static const int j=42;
        static constexpr float g=9.5f;
    };

    In this case, the i member of all instances of class X is initialized to 5 by the compiler-generated constructor, and the f member is initialized to 3.12. The static const data member j is initialized to 42, and the static constexpr data member g is initialized to 9.5.

    Since float and double are not of integral or enumeration type, such members must either be constexpr, or non-static in order for the initializer in the class definition to be permitted.

    Prior to C++11, only static const data members of integral or enumeration type could have initializers in the class definition.

     const 和 constexpr 变量之间的主要区别在于:const 变量的初始化可以延迟到运行时,而 constexpr 变量必须在编译时进行初始化。所有 constexpr 变量均为常量,因此必须使用常量表达式初始化。

    对于修饰Object来说,const并未区分出编译期常量和运行期常量,constexpr限定在了编译期常量。

    编译器常量的特点就是:它的值在编译期就可以确定。比如:const int i = 5;

    在运行时常量,它的值虽然在运行时初始化后不再发生变化,但问题就在于它的初始值要到编译时才能确定。比如:
    srand(clock());
    const int i = rand();
    虽然i的值在定义并初始化成不会再发生变化(除非你使用一些不符合标准的小技巧),但再聪明的编译器也无法在编译时确定它的值。

    编译期常量最常见的例子是编译时的常数定义,比如:
    const double PI = 3.1415926;
    运行期常量的最常见的例子是函数的常量参数(包括常引用,常指针参数)比如:
    void f(const string& s) {...}
    次常见的例子是类的非静态常量成员。
    ——这些都是一经初始化,不允许再发生变化的,但其初始值必须到运行时才能知道。

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    template <typename T>
    class testClass
    {
    public:
        static const int a = 5;
        static const long b = 3L;
        static const char c = 'c';
        static const double d = 100.1;
    };
    
    int main()
    {
        cout << testClass<int>::a << endl;
        cout << testClass<int>::b << endl;
        cout << testClass<int>::c << endl;
        //下面的语句出错,带有类内初始值设定项的静态数据成员必须具有不可变的常量整型
        cout << testClass<int>::d << endl;
    
        system("pause");
        return 0;
    }

    increment(++)实现(前置式及后置式),dereference(*)实现

    i++调用operator++(int), ++i调用operator++()

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    class INT
    {
        friend ostream& operator<<(ostream& os, const INT& i);
    public:
        INT(int i) :m_i(i) {};
        //自增然后得到值
        INT& operator++()
        {
            ++(this->m_i);
            return *this;
        }
        //先得到值然后自增
        const INT operator++(int)
        {
            INT temp = *this;
            ++(this->m_i);
            return temp;
        }
        //取值
        int& operator*() const
        {
            return (int&)m_i;
            //下面的语句会出错,因为将int&类型的引用绑定到const int类型的初始值设定项。由于函数是const成员函数导致
            //return m_i;
        }
    private:
        int m_i;
    };
    
    ostream& operator<<(ostream& os, const INT& i)
    {
        os << '[' << i.m_i << ']' << endl;
        return os;
    }
    
    int main()
    {
        INT I(5);
        cout << I++;
        cout << ++I;
        cout << *I;
    
        system("pause");
        return 0;
    }
  • 相关阅读:
    Angular27 指令
    Angular26 ng-content和ng-container、投影的使用
    denied: requested access to the resource is denied
    kali 扫描之burp Suite学习笔记1
    VMware的包格式vmdk转换为virtualBox的ova
    面试之leetcode分治-求众数,x幂等
    C/c++语言开源项目总结
    面试之哈希表leetcode
    面试之leetcode20堆栈-字符串括号匹配,队列实现栈
    面试之leetcode链表
  • 原文地址:https://www.cnblogs.com/ljygoodgoodstudydaydayup/p/4927315.html
Copyright © 2011-2022 走看看