struct IdString
{
std::string name;
int identifier;
};
IdString var3{"SomeName", 4};
IdString GetString()
{
return {"SomeName", 4}; //可以直接返回结构体
}
for (vector ::const_iterator itr = myvec.cbegin(); itr != myvec.cend(); ++itr)
for (auto itr = myvec.cbegin(); itr != myvec.cend(); ++itr)
for (auto &x : myvec.cbegin()) //用auto替换
int my_array[5] = {1, 2, 3, 4, 5};
for (int &x : my_array)
{x *= 2;}
for (auto &x : my_array)
{x *= 2;}
这种for语句还可以用于C型数组,初始化列表,和任何定义了begin()和end()来回返首尾迭代器的类型。
template <typename U, typename V>
auto foo(U u, V v) -> decltype(u*v){
return u*v;
}
//decltype并不会计算值,只会计算类型
这样就能明确u*v的类型了
template <typename LHS, typename RHS>
//以下要注意-> decltype(lhs+rhs)这个用法
auto AddingFunc(const LHS &lhs, const RHS &rhs) -> decltype(lhs+rhs)
{
return lhs + rhs;
}
class SomeType {
int number;
string name;
SomeType( int i, string& s ) : number(i), name(s){}
public:
SomeType( ) : SomeType( 0, "invalid" ){}
SomeType( int i ) : SomeType( i, "guest" ){}
SomeType( string& s ) : SomeType( 1, s ){ PostInit(); }
};
class BaseClass{
public:
BaseClass(int iValue);
};
class DerivedClass : public BaseClass{
public:
using BaseClass::BaseClass; //可以继承基类的构造函数,但是要不就全部继承,要不就一个都不要继承
};
void foo(char *);
void foo(int);
void foo(nullptr_t);
char* pc = nullptr; // OK
int * pi = nullptr; // OK
int i = nullptr; // error nullptr不能隐式转换为整数,也不能和整数做比较。
bool b = nullptr; // OK
foo(pc); // 调用foo(char *), 而不是 foo(int), 也不是void foo(nullptr_t);
foo(nullptr); // 调用foo(nullptr_t);
enum class myEnumeration : unsigned int
{
Val1,
Val2,
Val3 = 100,
Val4 /* = 101 */,
};
Enum1::Val1是有意义的表示法,而单独的Val1则否
此种枚举为类型安全的。枚举类别不能隐式地转换为整数;也无法与整数数值做比较。(表示式Enumeration::Val4 == 101会触发编译期错误)。这时候需要执行强制转换才能比较。
inline 是一种“用于实现的关键字”,而不是一种“用于声明的关键字”。一般地,用户可以阅读函数的声明,但是看不到函数的定义。
如下不构成内联函数:
inline void Foo(int x, int y); // inline 仅与函数声明放在一起
void Foo(int x, int y){}
而如下构成内联函数:
void Foo(int x, int y);
inline void Foo(int x, int y) // inline 与函数定义体放在一起{}
有的公司编码规范明确规定只用于本文件的函数要全部使用static关键字声明,这是一个良好的编码风格。
如果想多个文件共享变量,但是在头文件中声明了static变量,则头文件被包含了多少次,这个static变量就被创建了多少次,它们之间互不关联。
一个进程在内存中的分布如下图:
当你的程序中有很多个源文件的时候,你肯定会让某个源文件只提供一些外界需要的接口,其他的函数可能是为了实现这些接口而编写,这些其他的函数你可能并不希望被外界(非本源文件)所看到,这时候就可以用static修饰这些“其他的函数”。
static函数的作用域是本源文件,把它想象为面向对象中的private函数就可以了。
debug阶段要使用assert?assert中文解释是 断言 ,比如说,“我断言x一定大于0”。是用于排除错误的,而非异常。
assert可能默认是关闭的,此时需要在include前用宏打开:
#undef NDEBUG
#include <assert.h>
//...
aseert(exp); //exp为0时断言失败,不为0时断言成功,表示正确。
//...
assert()应该遵循使用原则,每次断言只能检验一个判断式。
assert(exp1 && exp2 && exp3);
//应该修改为
assert(exp1);
assert(exp2);
assert(exp3);
但是在 release版本应该关闭assert ,因其会造成较大的性能损耗,可以在代码测试或者merge之前,关闭assert
decltype与auto关键字一样,用于进行编译时类型推导
int n = 0, m = 0;
decltype(n + m) c = 0; //n+m 得到一个右值,符合推导规则一,所以推导结果为 int
decltype(n = n + m) d = c; //n=n+m 得到一个左值,符号推导规则三,所以推导结果为 int&
与auto效果相同,但是auto 只能用于类的静态成员,不能用于类的非静态成员(普通成员),如果我们想推导非静态成员的类型,这个时候就必须使用 decltype 了
using size_t = decltype(sizeof(0));//sizeof(a)的返回值为size_t类型
using ptrdiff_t = decltype((int*)0 - (int*)0);
using nullptr_t = decltype(nullptr);
vector<int >vec; typedef decltype(vec.begin()) vectype;
for (vectype i = vec.begin; i != vec.end(); i++) { //... }
//匿名struct
struct
{
int a;
int b;
}S;
decltype(S) s;
template <typename U, typename V>
auto foo(U u, V v) -> decltype(u*v){
return u*v;
}
原文:https://www.cnblogs.com/jerry323/p/12727751.html