最近在走读webrtc代码,碰到一些比较冷门的STL 的API,特此记录。
1. std::enable_if
C11新特性,简单的说,就是模板中,根据K值的结果,确定使用的函数。
int main()
{
int a = 128;
vector<string> s = { "today", "is", "Saturday" };
show(a);
show(s);
}
template <typename T>
typename enable_if<!has_iterator<T>::value, void>::type show(const T& x)
{
cout << x << endl;
}
template <typename T>
typename enable_if<has_iterator<T>::value, void>::type show(const T& x)
{
for (auto& i : x)
cout << i << endl;
}
2. std::lower_bound和std::upper_bound
一句话描述就是寻找距离预期值最近的指针地址(分别是 小于等于/大于等于)
a[i]={12,15,17,19,20,22,23,26,29,35,40,51};
用值21调用lower_bound(),返回一个指向22的iterator。用值22调用lower_bound(),也返回一个指向22的iterator。
3.std::forward
同样C11的新特性,这个直接参考 https://www.jianshu.com/p/b90d1091a4ff 写的,应该比较明确了。
std::forward只有在它的参数绑定到一个右值上的时候,它才转换它的参数到一个右值。
class Foo
{
public:
std::string member;
template<typename T>
Foo(T&& member): member{std::forward<T>(member)} {}
};
-
传递一个lvalue或者传递一个const lvaue
传递一个lvalue,模板推导之后 T = std::string&
传递一个const lvaue, 模板推导之后T = const std::string&
T& &&将折叠为T&,即std::string& && 折叠为 std::string&
最终函数为: Foo(string& member): member{std::forward<string&>(member)} {}
std::forward<string&>(member)将返回一个左值,最终调用拷贝构造函数 -
传递一个rvalue
传递一个rvalue,模板推导之后 T = std::string
最终函数为: Foo(string&& member): member{std::forward(member)} {}
std::forward(member) 将返回一个右值,最终调用移动构造函数; -
std::move和std::forward本质都是转换。std::move执行到右值的无条件转换。std::forward只有在它的参数绑定到一个右值上的时候,才转换它的参数到一个右值。
std::move没有move任何东西,std::forward没有转发任何东西。在运行期,它们没有做任何事情。它们没有产生需要执行的代码,一byte都没有。
4. std::optional
C14引入,简单的说,就是针对int等数字值,有了个判断是否初始化的机会。
std::optional<int> op;
if(op)
cout<<*op<<endl;
std::optional<int> op1 = 1;
if(op1)
cout<<*op1<<endl;
第一个op由于没有被初始化,所以它是一个无效值,将不会输出打印信息,第二个op被初始化为1,所以它是一个有效值,将会输出1