眾所周知,Cartographer源碼中使用大量c++11特性,為了更加絲滑地讀代碼,本文將記錄源碼閱讀過(guò)程中遇到的奇淫巧技,以了解及學(xué)習(xí)使用這些特性。
- constexpr
The keyword constexpr was introduced in C++11 and improved in C++14. It means constant expression. Like const, it can be applied to variables: A compiler error is raised when any code attempts to modify the value. Unlike const, constexpr can also be applied to functions and class constructors. constexpr indicates that the value, or return value, is constant and, where possible, is computed at compile time.
Microsoft Docs
至于上文中提到的c++14的改進(jìn),是為了避免在編譯過(guò)程中推斷變量(函數(shù)的返回值等)的類型甚至是計(jì)算變量的值耗費(fèi)過(guò)長(zhǎng)時(shí)間,而對(duì)被constexpr關(guān)鍵字修飾的變量類型或函數(shù)返回值進(jìn)行了限制(必須為Literal types),所謂的literal types包括:
- void
- scalar types
- references
- Arrays of void, scalar types or references
- A class that has a trivial destructor, and one or more constexpr constructors that are not move or copy constructors. Additionally, all its non-static data members and base classes must be literal types and not volatile.
- 匿名命名空間(unnamed namespace)
顧名思義,匿名命名空間是指定義了命名空間,卻不為該命名空間指定名稱:
namespace{
//something
}
對(duì)于這樣用的原因,網(wǎng)上有很多解釋,稍微通俗的解釋是:
Having something in an anonymous namespace means it's local to this translation unit (.cpp file and all its includes) this means that if another symbol with the same name is defined elsewhere there will not be a violation of the One Definition Rule (ODR).
All anonymous namespaces in the same file are treated as the same namespace and all anonymous namespaces in different files are distinct.
簡(jiǎn)言之,就是說(shuō)匿名命名空間會(huì)使命名空間內(nèi)的所有聲明和定義失去外部鏈接性,但是在當(dāng)前translation unit內(nèi)具有鏈接性,跟static 關(guān)鍵字很像,但是又有所區(qū)別。同時(shí)可以避免與其他變量的命名沖突。
- 作用域解析符::
用一段代碼解釋幾乎所有的作用域解析符"::"的用法:
const int x = 5;
namespace foo {
const int x = 0;
}
int bar() {
int x = 1;
return x;
}
struct Meh {
static const int x = 2;
}
int main() {
std::cout << x; // => 5
{
int x = 4;
std::cout << x; // => 4
std::cout << ::x; // => 5, this one looks for x outside the current scope
}
std::cout << Meh::x; // => 2, use the definition of x inside the scope of Meh
std::cout << foo::x; // => 0, use the definition of x inside foo
std::cout << bar(); // => 1, use the definition of x inside bar (returned by bar)
}
PS:Cartographer源碼中經(jīng)常使用::前不指定命名空間名稱的用法。