一、lambda不可以是template
二、lambda目前已不鼓励函数指明异常明细
三、lambda
1、 [...] {...}
2、 [...] (...) (mutable) (throwSpec) (->retType) {...}
3、 [=]意味着外部作用域以by value方式传递给lambda,可以读取数据,但不能改动
4、 [&]意味着外部作用域以by reference方式传递给lambda,可以读取数据,也可以改动
5、 为了获得by value 和 by reference 的混合体,可以声明lambda为mutable,被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中
四、关键字decltype可让编译器找出表达式类型:decltype(coll)::value_type elem
五、可以将一个函数的返回类型声明于参数列表后:auto add(T1 x, T2 y) -> decltype(x + y);
六、scoped enumeration重点在于enumerate之后指明关键字class。不会隐式转换为int: enum class Salutation : char {mr, ms, co, none};
七、新的继承类型
1、char16_t和char32_t
2、long long和unsigned long long
3、std::nullptr_t
八、关键字typename用来指明紧跟其后的是一个类型:typename T::SubType* ptr;
1、typename 用来表明 SubType是个类型,定义于class T内
2、如果没有typename, SubType会被视为一个static成员,表明 类型T的数值SubType 乘以 ptr
九、main()只有两种定义具备可移植性:
1、 int main()
2、int main(int argc, char* argv[]) / int main(int argc, char** argv)。 argc表明一共接受到了多少个参数,argv是命令行实参形成的array,也可以定义成char**;
class P
{
public:
P(int, int);
explicit P(int, int, int);
void fp(const P&);
private:
int x, y, z;
};
P::P(int x1, int y1) : x(x1), y(y1), z(0)
{
}
P::P(int x1, int y1, int z1) : x(x1), y(y1), z(z1)
{
}
void P::fp(const P& lhs)
{
cout << "--------" << endl;
cout << lhs.x << endl;
cout << lhs.y << endl;
cout << lhs.z << endl;
cout << "--------" << endl;
}
void foo(P& x ) {}
void foo(P&& x){}
void foo(const P& x){}
// 如果有void foo(P& x )而没有void foo(P&& x), x可以是lvalue但不能是rvalue
//如果有void foo(const P& x)而没有void foo(P&& x), x可以是lvalue也可以是rvalue
//如果只有void foo(P&& x),则x可以是rvalue但不能是lvalue
template<typename T>
void printElements(const T& coll)
{
for (const auto& elem : coll)
{
cout << elem << ends;
}
cout << endl;
}
// 模板可变参数
// 模板可变参数递归掉函数并传入其余实参,必须提供一个non-template重载函数才结束递归
template<typename T>
void print(const T& arg)
{
cout << arg << endl;
}
template<typename T, typename... Types>
void print(const T& arg, const Types&... args)
{
cout << arg << endl;
print(args...);
}
// 带别名的模板
template<typename T>
using Vec = vector<T>;
// Vec<int> coll; // vector<int> coll;
// 新的函数声明语法
template<typename T1, typename T2>
// 可以将一个函数的返回类型声明于参数列表后
auto add(T1 x, T2 y) -> decltype(x + y);
//关键字typename用来指明紧跟其后的是一个类型
template<typename T>
class MyClass
{
// typename 用来表明 SubType是个类型,定义于class T内
// 如果没有typename, SubType会被视为一个static成员,表明 类型T的数值SubType 乘以 ptr
//T::SubType* ptr;
typename T::SubType* ptr;
};
class Q
{
// 基于SubType必须是个类型,任何被用来替换T的类型,都必须提供一个内层类型SubType
typedef int SubType;
// 也可以是个抽象数据类型,如class
//class SubType;
};
// 成员模板
template <typename T>
class MyClass2
{
private:
T value;
public:
void assign(const MyClass2<T>& x)
{
value = x.value;
}
};
void foo2()
{
MyClass2<double> d;
MyClass2<int> i;
d.assign(d);
//d.assign(i);// 类型错误
}
template <typename T>
class MyClass3
{
private:
T value;
public:
template <typename X>
void assign(const MyClass3<X>& x)
{
// 由于类型不同,不能直接用private的value
value = x.getValue();
}
T getValue() const
{
return value;
}
};
void foo3()
{
MyClass3<double> d;
MyClass3<int> i;
d.assign(d);
d.assign(i);
}
//main()只有两种定义具备可移植性
// int main()
// int main(int argc, char* argv[]) / int main(int argc, char** argv)
// argc表明一共接受到了多少个参数
// argv是命令行实参形成的array,也可以定义成char**;
// main()返回类型必须是int
int main()
{
P x(1, 2);
//初值列
P y{ 3, 4 };
P z{ 5, 6, 7 };
P v = { 8, 9 };
//P v = { 1, 2, 3 }; // 复制列表初始化不能使用标记为explicit的构造函数
x.fp({ 11, 22 });
//x.fp({ 1,2,3 });// 复制列表初始化不能使用标记为explicit的构造函数
x.fp(P{ 13, 14 });
x.fp(P{ 15, 16, 17 });
vector<int> ivec{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// 不定义引用
for (auto elem : ivec)
{
elem *= 3;
}
cout << "不定义引用" << endl;
printElements(ivec);
// 定义引用
for (auto& elem : ivec)
{
elem *= 3;
}
cout << "定义引用" << endl;
printElements(ivec);
R"(\ns)";
u8"hello";
u"hello";
U"hello";
L"hello";
// [...] {...}
// [...] (...) (mutable) (throwSpec) (->retType) {...}
[] {cout << "hello" << endl; };
[] {cout << "hello" << endl; }(); // 直接使用
// 传递给对象
auto l = [] {cout << "hello" << endl; };
l();
auto l2 = [](const string& s) {cout << s << endl; };
l2("hello");
int lx = 0;
int ly = 42;
// [=]意味着外部作用域以by value方式传递给lambda,可以读取数据,但不能改动
// [&]意味着外部作用域以by reference方式传递给lambda,可以读取数据,也可以改动
auto l3 = [lx, &ly] {
cout << lx << endl;
cout << ly << endl;
++ly; //正确
//++lx; // 错误
};
//为了获得by value 和 by reference 的混合体,可以声明lambda为mutable
//被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中
auto l4 = [lx]() mutable {
cout << lx << endl;
++lx; // 正确
};
vector<int> coll;
// 关键字decltype可让编译器找出表达式类型
decltype(coll)::value_type elem;
// scoped enumeration
// 重点在于enumerate之后指明关键字class
// 优点
// 1、不会隐式转换为int
// 2、如果数值(如mr)不在enumeration被声明的作用域内,必须使用Salutation::mr
enum class Salutation : char {mr, ms, co, none};
//新的继承类型
// char16_t和char32_t
// long long和unsigned long long
// std::nullptr_t
// 如果不想以main()返回的方式结束程序,通常可以调用exit(), quick_exit(), terminate()
return 0;
}