C++20新特性—span与bind_front

std::span

span表示一段连续的内存,像数组一样,但它不拥有或管理这段内存,即它是“view”,大致上就是struct { T * ptr; size_t length; 一组获取内部元素的函数 },所以span具有三个特征:

  • 连续内存
  • 轻量级
  • view

span的三个特征决定了它主要应用场合包括:

  • C风格的(T *,size_t length)的包装器,这样,对C风格“数组”的操作,可以用C++容器类操作的风格来代替;
  • 类似于string_view对string的作用,span可以代替如vector&这样的表达作为函数参数。

上面两点都可以提高代码的可读性和安全性。
下面是一个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

std::bind_front定义在中,与std::bind功能类似,都可以对函数进行包装,然后在方便的时候调用。
对于函数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就显得呆板些,而不能完成。

你可能感兴趣的:(C/C++,c++)