将 string 类型,转换为模板类型
1 | template <typename P0> |
将模板类型 ,转换为string 类型
1 | template <class T> |
Mach内核获得Cpu使用率百分比
1 | NSInteger ARDGetCpuUsagePercentage() { |
题外话,更具体的虚拟内存、物理内存、CPU 使用等等获取方法在以下链接
字节对齐
8个字节对齐1
2
3
4
5
6
7
static inline uint32_t word_align(uint32_t x) {
return static_cast<uint32_t>((x + WORD_MASK) & ~WORD_MASK);
}
static inline size_t word_align(size_t x) {
return (x + WORD_MASK) & ~WORD_MASK;
}
指针的二进制、十进制、八进制输出
二进制1
2const void* p
std::cout << std::bitset<sizeof(int32_t)*8>((uintptr_t)p) << std::endl;
十进制1
2const void* p
std::cout << (uintptr_t)p << std::endl;
十六进制1
2const void* p
std::cout << std::hex << (uintptr_t)p << std::endl;
八进制1
2const void* p
std::cout << std::oct << (uintptr_t)p << std::endl;
利用模板函数将数字转为字符串
1 | const char digits[] = "9876543210123456789"; const char* zero = digits + 9; |
模板静态检测传入参数是否符合规格
1 | template <typename T, std::ptrdiff_t Size> class ArrayViewBase { static_assert(Size > 0, "ArrayView Size must be variable or non-negative"); }; |
内存屏障
例子中使用内存屏障,防止编译器进行优化,让读取 ptr
的操作要在 memset 方法后才进行1
void ExplicitZeroMemory(void* ptr, size_t len) {
memset(ptr, 0, len);
// 内存屏障 __asm__ __voilate__("" ::: "memory");
/* As best as we can tell, this is sufficient to break any optimisations that
might try to eliminate "superfluous" memsets. If there's an easy way to
detect memset_s, it would be better to use that. */
__asm__ __volatile__("" : : "r"(ptr) : "memory");
}
PS: 题外话
C与C++语言中,volatile关键字意图允许内存映射的I/O操作。这要求编译器对此的数据读写按照程序中的先后顺序执行,不能对volatile 内存的读写重排序。因此关键字 volatile 并不保证是一个内存屏障。
对于Visual Studio 2003,编译器保证对 volatile 的操作是有序的,但是不能保证处理器的乱序执行
SFINAE && std::enable_if<>
SFINAE是英文 Substitution failure is not an error 的缩写,意思是匹配失败不是错误。
我们可以利用 std::enable_if<>
来腿短模板成不成立
1 | // 模板方法1 |
当传入类型 T 的 std::is_trivial 为 false 的时候,就会调用模板方法2
, 否则为 模板方法1
如何模拟 GCD 中的 dispatch_async 和 dispatch_sync
1 | CFRunLoopRef m_cfRunLoop([runLoop getCFRunLoop]) |