span
span的三个特征决定了它主要应用场合包括:
上面两点都可以提高代码的可读性和安全性。
下面是一个std::span的示例。
template [[nodiscard]]
constexpr auto slide(std::span s, std::size_t offset, std::size_t width) {
return s.subspan(offset, offset + width <= s.size() ? width : 0U);
}
template [[nodiscard]]
constexpr bool starts_with(std::span data, std::span prefix) {
return data.size() >= prefix.size()
&& std::equal(prefix.begin(), prefix.end(), data.begin());
}
template [[nodiscard]]
constexpr bool ends_with(std::span data, std::span suffix) {
return data.size() >= suffix.size()
&& std::equal(data.end() - suffix.size(), data.end(),
suffix.end() - suffix.size());
}
template [[nodiscard]]
constexpr bool contains(std::span span, std::span sub) {
return std::search(span.begin(), span.end(), sub.begin(), sub.end())
!= span.end();
}
void print(const auto& seq) {
for (const auto& elem : seq) std::cout << elem << ' ';
std::cout << '\n';
}
int main()
{
int a[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
std::vector b={ 8, 7, 6 };
auto s1 = slide(std::span{a}, 3, 4);
print(s1);
std::cout<
上例中,通过span对数组的包装,使得对数组的操作完全变成了一种类似“集合”的操作。
std::bind_front定义在
对于函数f(arg1,arg2…)
std::bind的用法是
在定义时,bindfun=std::bind(f,[arg,placeholder...]),arg和placeholder的总个数与f的参数一致;
使用时,bindfun([arg,..]),arg的个数与placeholder的个数一致,用以替代定义时的placeholder。
std::bind_front的用法是
在定义时,bindfun=std::bind_front(f,[arg…]),arg是f的前n个参数(n为0至f参数的个数,bind front的意思由此而来,就是绑定前n个参数);
使用时,bindfun([arg,…]),arg是剩余的f的参数。
void test_bind()
{
auto calc=[](int a, int b, int c) { return a+b-c;};
auto aa = std::bind_front(calc, 1,2);
std::cout << aa (3)<<"\n";
auto bb = std::bind_front(calc, 1,2,3);
std::cout << bb ()<<"\n";
auto cc=std::bind(calc, 1,std::placeholders::_2,std::placeholders::_1);
std::cout<
从上面的示例,如果仅按顺序bind调用,std::bind_front的写法要简单些,但使用placeholder占位符后,可以更灵活的方式“掩盖”原有的参数调用方式,std::bind_front就显得呆板些,而不能完成。