1, left value vs right value
In concept (though not always in practice), rvalues correspond to temporary objects returned from functions, while lvalues correspond to objects you can refer to, either by name or by following a pointer or lvalue reference. A useful heuristic to determine whether an expression is an lvalue is to ask if you can take its address.
2, auto
推断规则同template,如下
template<T>
void fun(paratype )
fun(expr)
auto a = 1;
const auto& b = a; //auto = T
特例
auto a= {1,2,3} //支持initilizer_list
fun({1,2,3}) //不支持,没啥原因,just sb rules
auto 在一些不可见的代理类型中会出错,比如vector<bool>的底层实现是bit
3, safe design
- nullptr vs 0, NULL
void fun(int)
void fun(void*)
fun(0) //fun(int)
fun(NULL) //fun(int)
fun(nullptr) //fun(void*)
C++ 中 #define NULL 0, 容易产生二义性
4, move semantics perfect forwarding
move: unconditionally cast to right value reference (static<T&&> para)
perfect forwarding: cast to right value reference only the parameter is initialized with right value ref
void process(const Widget& lvalArg); // process lvalues
void process(Widget&& rvalArg); // process rvalues
template<typename T> // template that passes
void logAndProcess(T&& param) // param to process
{
auto now = // get current time
std::chrono::system_clock::now();
makeLogEntry("Calling 'process'", now);
process(std::forward<T>(param));
}
Widget w;
logAndProcess(w); // call with lvalue
logAndProcess(std::move(w)); // call with rvalue