C++奇淫巧技汇总

众所周知,Cartographer源码中使用大量c++11特性,为了更加丝滑地读代码,本文将记录源码阅读过程中遇到的奇淫巧技,以了解及学习使用这些特性。

  • 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的改进,是为了避免在编译过程中推断变量(函数的返回值等)的类型甚至是计算变量的值耗费过长时间,而对被constexpr关键字修饰的变量类型或函数返回值进行了限制(必须为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
}

对于这样用的原因,网上有很多解释,稍微通俗的解释是:

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.
简言之,就是说匿名命名空间会使命名空间内的所有声明和定义失去外部链接性,但是在当前translation unit内具有链接性,跟static 关键字很像,但是又有所区别。同时可以避免与其他变量的命名冲突。

  • 作用域解析符::
    用一段代码解释几乎所有的作用域解析符"::"的用法:
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源码中经常使用::前不指定命名空间名称的用法。

你可能感兴趣的:(C++奇淫巧技汇总)