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-
staticdata members,static constexprdata members, andstatic constdata 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
imember of all instances of classXis initialized to5by the compiler-generated constructor, and thefmember is initialized to3.12. Thestatic constdata memberjis initialized to42, and thestatic constexprdata membergis initialized to9.5.Since
floatanddoubleare not of integral or enumeration type, such members must either beconstexpr, or non-staticin order for the initializer in the class definition to be permitted.Prior to C++11, only
static constdata 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; }

浙公网安备 33010602011771号