在C/C++中,我们经常会像下面的代码那样使用一个指向函数的指针,我们称之为函数指针:
// demo.c
#include <stdio.h>
int func(int a) {
return a + 1;
}
int main(int argc, char* argv[]) {
int (*f)(int) = func;
printf("%p\n", f);
return 0;
}
上面的例子中,我们定义了一个函数func
,然后通过函数指针f
指向func
,接着使用print
函数打印指针变量f
指向
的地址。代码平淡无奇,接着我们编译代码,然后使用objdump -D...
std::list splice 简介
splice
函数通过重新排列链表指针,将一个std::list
中的节点转移到另一个std::list
中。在元素的转移过程中不会触发元素的拷贝或者移动。因此,调用splice
函数之后,元素现有的引用和迭代器都不会失效。
下面是一个将listA
中所有节点附加到listB
的一个简单代码示例,转移的过程不会导致listA
中元素的引用和迭代器失效:
// Note: c++17 required below. (For CTAD(Class template argument deducation))
std::list listA{1, 2, 3};
std::list listB{4, 5, 6...
前言
c++11 对智能指针做了很大的优化,废弃了 c++98 中的auto_ptr
,引入了三种新的智能指针:unique_ptr
,shared_ptr
,weak_ptr
。
本文将针对unique_ptr
的一些使用技巧做一些整理和归纳。在正式开始之前,我们首先来回顾一下unique_ptr
的特点:一个unique_ptr
对象内包含一个原始指针,该unique_ptr
对象负责管理原始指针的生命周期。
一个unique_ptr
对象始终是其关联的原始指针的唯一拥有者。
在了解了unique_ptr
的特点之后,我们来具体看看日常开发中unique_ptr
的一些使用场景和技巧。
一些场景
本地对象指针
在开发中,我们经常会遇到或者写出类...
constexpr 是 c++11 引入的关键字,用于编译时常量和常量表达式。而 c++17 将这一特性做了增强,引入了 constexpr if
,
使得编译器在编译时(compile time)能够做分支判断,从而有条件的编译代码。
下面可以通过一个简单的例子来看看constexpr if
的用法:
#include <iostream>
#include <type_traits>
template<typename T> auto getValue(T t)
{
if constexpr (std::is_pointer<T>::value) {...
对于熟悉 c99 的人来说,Designated Initializers 并不算是什么新鲜事物,然而 c++直到 c++20 才正式支持这一特性。 虽然在 c++20 之前,像 GCC 这样的编译器通过扩展的形式已经对该特性做了支持,但是随着 c++20 将其纳入新标准,这一特性将在所有编译器中得到支持。
基本用法
Designated Initialization 是聚合初始化(Aggregate Initialization)的一种形式。 在 c++20 中,聚合类型(Aggregate types)是指:
- 数组类型
- 具备如下特性的 class 类型:
- has no private or protected...
对于一个标准的 c++容器来说,我们可以很容易在运行时使用迭代器和 range-based for
loop 来遍历其中的每一个元素。但是对于std::tuple
,却不能像普通的容器那样去遍历它。
std::tuple 简介
std::tuple
是一个具有固定大小,包含不同类型值的集和。与之相似的是std::pair
,只不过std::pair
只能容纳两个元素,
而std::tuple
可以容纳许多元素:
std::tuple<int, double, const char*> tup {42, 10.5, "hello"};
// or with CTAD(class template argument...
string_view 简介
std::string_view
是 c++17 中新增的一种类型。其核心理念是,能够让我们在传统的 C++03 风格的具体性和泛型编程之间找到一个很好的折衷点。
在 C++17 标准之前,我们通常只能在粗糙的不严谨的模板实现和相对严谨但是有着冗长约束的模板之间做出选择。举个简单的例子:
// c++03 style
class Widget
{
std::string name_;
public:
void setName(const char* new_name);
void setName(const std::string& new_name);
};
// ...