Boost C++ 库

世界上最受推崇、设计最精妙的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ Coding Standards

Boost.Compat - Boost C++ 函数库

概述

Boost.Compat 是对稍后 C++ 标准中添加的标准组件的 C++11 实现的集合。其目标受众是支持较低 C++ 标准但希望使用后续标准中添加的组件的 Boost 库作者。

包含在 Boost.Compat 中的标准如下:

  • 实现应该是相对简单且仅限头文件的。

  • 组件必须完全实现标准功能,不得有偏差或扩展。这允许(但不要求)在标准组件可用时,实现可以是一个简单的 `using` 声明。

  • 组件不得依赖任何 Boost 库,除了 Boost.Config、Boost.Assert 或 Boost.ThrowException。

  • 组件不得是可见于库 API 的词汇类型。用户永远不应看到 `boost::compat` 类型;Compat 类型的用法应仅限于库实现。

修订历史

1.89.0 版本中的变化

  • 添加了 `move_only_function.hpp`。

1.87.0 版中的更改

  • 添加了 `to_array.hpp`(由 Ruben Perez Hidalgo 贡献)。

1.86.0 中的更改

  • 添加了 `bind_front.hpp`、`bind_back.hpp`、`invoke.hpp`、`mem_fn.hpp`、`integer_sequence.hpp` 和 `type_traits.hpp`。

  • 添加了 `function_ref.hpp`。

1.83.0 版的更改

  • 添加了 `latch.hpp`,这是 `std::latch` 的一个实现(由 Christian Mazakas 贡献)。

  • 添加了 `shared_lock.hpp`,这是 `std::shared_lock` 的一个(部分)实现(由 Christian Mazakas 贡献)。

<boost/compat/bind_back.hpp>

描述

头文件 `<boost/compat/bind_back.hpp>` 实现 C++20 函数 `std::bind_back`。

`bind_back` 是 `std::bind` 的一个受限变体。它仅支持将函数对象的最后几个参数绑定到特定参数值。

示例

struct X
{
    void f(int a, int b) const noexcept;
};

int main()
{
    auto fn = boost::compat::bind_back(&X::f, 1, 2);

    X x;
    fn(x); // calls x.f(1, 2)
}

提要

namespace boost
{
namespace compat
{

template<class F, class... A> auto bind_back(F&& f, A&&... a);

} // namespace compat
} // namespace boost

bind_back

template<class F, class... A> auto bind_back( F&& f, A&&... a );
返回

函数对象 `fn`,使得 `fn(b…​)` 等同于 `invoke(f, b…​, a…​)`。

<boost/compat/bind_front.hpp>

描述

头文件 `<boost/compat/bind_front.hpp>` 实现 C++20 函数 `std::bind_front`。

`bind_front` 是 `std::bind` 的一个受限变体。它仅支持将函数对象的前几个参数绑定到特定参数值。

示例

struct X
{
    void f(int a, int b) const noexcept;
};

int main()
{
    X x;
    auto fn = boost::compat::bind_front(&X::f, &x);

    fn(1, 2); // calls x.f(1, 2)
}

提要

namespace boost
{
namespace compat
{

template<class F, class... A> auto bind_front(F&& f, A&&... a);

} // namespace compat
} // namespace boost

bind_front

template<class F, class... A> auto bind_front(F&& f, A&&... a);
返回

函数对象 `fn`,使得 `fn(b…​)` 等同于 `invoke(f, a…​, b…​)`。

<boost/compat/function_ref.hpp>

描述

头文件 `<boost/compat/function_ref.hpp>` 实现 C++26 类 `std::function_ref`。

`function_ref` 是一个轻量级的多态函数包装器,它只存储指向提供的 Callable 对象和指向未指定函数的指针,这意味着它不参与 Callable 的所有权,也不分配内存。`function_ref` 的所有特化都满足 TriviallyCopyable

`function_ref` 支持 `const` 和 `noexcept` 的所有组合,并且对于编写高阶函数很有用,因为它可以避免模板参数或分配(正如 `std::function` 所熟知的那样)。

示例

int add(int x, int y) noexcept { return x * 10 + y; }

auto add2 = [](int x, int y) { return x * 100 + y; };

std::vector<boost::compat::function_ref<int(int, int)>> fns;
fns.push_back({add});
fns.push_back({add2});

for (auto fn : fns) {
  std::cout << fn(1, 2) << std::endl;
}

提要

namespace boost
{
namespace compat
{

template <class... S>
struct function_ref;

// cv is either `const` or empty
// noex is either `true` or `false`
template<class R, class... ArgTypes>
class function_ref<R(ArgTypes...) cv noexcept(noex)> {
public:
  template<class F> function_ref(F*) noexcept;
  template<class F> function_ref(F&&) noexcept;
  template<auto f> function_ref(nontype_t<f>) noexcept;
  template<auto f, class U> function_ref(nontype_t<f>, U&&) noexcept;
  template<auto f, class T> function_ref(nontype_t<f>, cv T*) noexcept;

  function_ref(const function_ref&) noexcept = default;
  function_ref& operator=(const function_ref&) noexcept = default;
  template<class T> function_ref& operator=(T) = delete;

  R operator()(ArgTypes...) const noexcept(noex);
};

} // namespace compat
} // namespace boost

构造函数

函数指针构造函数

template<class F> function_ref(F* fn) noexcept;
前置条件

`fn` != `nullptr`。

效果

构造一个 `function_ref`,该 `function_ref` 使用提供的函数指针作为其 Callable。

调用 `function_ref` 等同于 `invoke_r<R>(f, call-args…​)`。

对象构造函数

template<class F> function_ref(F&& fn) noexcept;
效果

构造一个 `function_ref`,它存储提供的 Callable 对象 `fn` 的地址。此重载仅在 `fn` 不是指向成员的指针或指向成员函数的指针时才参与解析。

调用 `function_ref` 等同于:+ `invoke_r<R>(static_cast<cv T&>(f), call-args…​)`。

指向成员函数的指针构造函数

template<auto f> function_ref(nontype_t<f>) noexcept;
效果

使用提供的指向成员函数的指针构造一个 `function_ref`。此重载仅在 `f` 是指向成员的指针或指向成员函数的指针时才参与解析。

调用 `function_ref` 等同于:`invoke_r<R>(f, class-args)`。

示例
struct point { int x = 1, y = 2; };

point p;
compat::function_ref<int(point const&)> f(compat::nontype_t<&point::x>{});

BOOST_TEST_EQ(f(p), 1);

绑定对象构造函数

template<auto f, class U> function_ref(nontype_t<f>, U&&) noexcept;
效果

使用提供的指向成员的指针或指向成员函数的指针以及对要绑定到的对象的引用来构造一个 `function_ref`。

如果 `is_rvalue_reference_v<U&&>` 为 false,则此重载仅参与解析。

示例
struct point { int x = 1, y = 2; };

point p;
compat::function_ref<int()> f(compat::nontype_t<&point::x>{}, p);

BOOST_TEST_EQ(f(), 1);

绑定指针构造函数

template<auto f, class T> function_ref(nontype_t<f>, cv T*) noexcept;
效果

使用提供的指向成员的指针或指向成员函数的指针以及指向对象的指针来构造一个 `function_ref`。

示例
struct point { int x = 1, y = 2; };

point p;
compat::function_ref<int()> f(compat::nontype_t<&point::x>{}, &p);

BOOST_TEST_EQ(f(), 1);

复制构造函数

function_ref(const function_ref&) noexcept = default;
效果

`function_ref` 是一个 TriviallyCopyable 类型。

成员函数

调用运算符

R operator()(ArgTypes...) const noexcept(noex);
效果

通过转发提供的参数来调用底层 Callable 对象。

赋值

复制赋值

function_ref& operator=(const function_ref&) noexcept = default;
template<class T> function_ref& operator=(T) = delete;
效果

`operator=(T)` 参与重载解析,如果

  • `T` 与 `function_ref` 不同

  • `is_pointer_v<T>` 为 `false`。

<boost/compat/move_only_function.hpp>

描述

头文件 `<boost/compat/move_only_function.hpp>` 实现 C++23 类 std::move_only_function

`move_only_function` 是一个多态包装器,它存储和管理一个 Callable,只要求该类型支持移动构造和移动赋值。这与常用的 `std::function` 不同,后者要求底层被管理对象是可复制的。

`move_only_function` 支持 `const`、`noexcept` 和引用限定符(无、`&`、`&&`)的所有组合。

示例

struct moveonly
{
    std::unique_ptr<int> p_ = std::make_unique<int>( 1234 );
    auto operator()( int x ) noexcept { return *p_ + x; }
};

boost::compat::move_only_function<int( int ) noexcept> f( moveonly{} );
std::cout << f( 4321 ) << std::endl;

提要

namespace boost {
namespace compat {

template<class... S>
class move_only_function;

template< class T >
struct in_place_type_t { explicit in_place_type_t() = default; };

template<class R, class ...Args>
class move_only_function<R( Args... ) /* cv */ /* ref */ noexcept( /* noex */)>
{
    move_only_function() noexcept;
    move_only_function( std::nullptr_t ) noexcept;

    template<class F>
    move_only_function( F&& f );

    template<class T, class ...CArgs>
    explicit move_only_function( in_place_type_t<T>, CArgs&& ... args );

    template<class T, class U, class ...CArgs>
    explicit move_only_function( in_place_type_t<T>,
                                 std::initializer_list<U> il, CArgs&& ... args );

    move_only_function( move_only_function const& ) = delete;
    move_only_function( move_only_function&& ) = default;

    ~move_only_function() = default;

    move_only_function& operator=( move_only_function&& rhs );
    move_only_function& operator=( std::nullptr_t ) noexcept;
    template<class F> move_only_function& operator=( F&& f );

    friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept;
    friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept;

    void swap( move_only_function& rhs ) noexcept;
    friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept;

    explicit operator bool() const noexcept;

    R operator()( Args... args ) /* cv */ /* ref */ noexcept( /* noex */ );
};

} // namespace compat
} // namespace boost

构造函数

默认构造函数

move_only_function() noexcept;
效果

构造一个空的 `move_only_function`,它不管理任何对象。

空构造函数

move_only_function( std::nullptr_t ) noexcept;
效果

使用 `nullptr` 值显式构造一个空的 `move_only_function`。等同于默认构造。

对象构造函数

template<class F>
move_only_function( F&& f );
效果

给定 `using VT = decay_t<F>`,使用 `forward<F>(f)` 直接构造 `VT` 的实例并将其存储为目标对象。

如果 `F` 是一个空函数指针、指向成员的指针或 `move_only_function` 的特化,则构造的 `move_only_function` 为空。

限制
  • `remove_cv_ref<F>` 不是 `move_only_function` 的同类型

  • `remove_cv_ref<F>` 不是 `in_place_type_t` 的特化

  • `T` 必须可以使用提供的 cvref 限定符和提供的参数类型进行调用

就地构造函数

template<class T, class ...CArgs>
explicit move_only_function( in_place_type_t<T>, CArgs&& ... args );
效果

使用提供的参数直接构造类型为 `T` 的对象,并将其存储为目标对象。

限制
  • `is_constructible_v<T, CArgs…​>` 必须为 true

  • `T` 必须可以使用提供的 cvref 限定符和提供的参数类型进行调用

列表就地构造函数

template<class T, class U, class ...CArgs>
explicit move_only_function( in_place_type_t<T>,
                             std::initializer_list<U> il, CArgs&& ... args );
效果

使用提供的 `initializer_list` 和参数直接构造类型为 `T` 的对象,并将其存储为目标 Callable。

限制
  • `is_constructible_v<T, std::initializer_list<U>&, CArgs…​>` 必须为 true

  • `T` 必须可以使用提供的 cvref 限定符和提供的参数类型进行调用

移动构造函数

move_only_function( move_only_function&& f ) = default;
效果

将 `f` 管理的对象的所有权转移给 `*this`。此操作完成后,`f` 将为空,不管理任何对象。

赋值

移动赋值

move_only_function& operator=( move_only_function&& rhs );
效果

释放当前管理的对象,并在适用时接管 `rhs` 管理的对象的所有权。移动后 `rhs` 将为空。

空赋值

move_only_function& operator=( std::nullptr_t ) noexcept;
效果

在适用时,释放当前管理的对象。

可调用赋值

template<class F> move_only_function& operator=( F&& f );
效果

释放当前管理的对象,然后执行等同于:`move_only_function(std::forward<F>(f)).swap(*this)` 的操作。

Utility

空相等

friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept;
friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept;
效果

返回 `fn` 是否包含目标对象。

Swap

void swap( move_only_function& rhs ) noexcept;
friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept;
效果

交换管理的对象。

调用

布尔转换

explicit operator bool() const noexcept;
效果

如果 `*this` 管理一个对象,则返回 `true`,否则返回 `false`(如果 `*this` 为空)。

调用运算符

R operator()( Args... args ) /* cv */ /* ref */ noexcept( /* noex */ );
前置条件

`*this` 当前管理一个对象。

效果

调用底层目标对象。等同于

return INVOKE<R>(static_cast<F inv-quals>(f), std::forward<Args>(args)...);

其中 `f` 是目标对象,而 *inv-quals* 由标准定义

  • 如果 *ref* 为空,则 *inv-quals* 为 *cv&*,

  • 否则,*inv-quals* 为 *cv ref*。

<boost/compat/integer_sequence.hpp>

描述

头文件 `<boost/compat/integer_sequence.hpp>` 实现 C++14 工具 `std::integer_sequence`、`std::index_sequence`、`std::make_integer_sequence`、`std::make_index_sequence` 和 `std::index_sequence_for`。

提要

namespace boost
{
namespace compat
{

template<class T, T... I> struct integer_sequence;

template<class T, T N> using make_integer_sequence = /*...*/;

template<std::size_t... I> using index_sequence = /*...*/;

template<std::size_t N> using make_index_sequence = /*...*/;

template<class... T> using index_sequence_for = /*...*/;

} // namespace compat
} // namespace boost

integer_sequence

template<class T, T... I> struct integer_sequence {};

make_integer_sequence

template<class T, T N> using make_integer_sequence = /*...*/;

`make_integer_sequence<T, N>` 是 `integer_sequence<T, 0, 1, 2, …​, N-1>` 的别名。

index_sequence

template<std::size_t... I> using index_sequence = integer_sequence<std::size_t, I...>;

make_index_sequence

template<std::size_t N> using make_index_sequence = make_integer_sequence<std::size_t, N>;

index_sequence_for

template<class... T> using index_sequence_for = make_integer_sequence<std::size_t, sizeof...(T)>;

<boost/compat/invoke.hpp>

描述

头文件 `<boost/compat/invoke.hpp>` 实现 C++17 函数 `std::invoke`、C++23 函数 `std::invoke_r` 以及相关的工具 `invoke_result_t`、`is_invocable`、`is_invocable_r`、`is_nothrow_invocable` 和 `is_nothrow_invocable_r`。

`invoke(f, a…​)` 通常返回 `f(a…​)`,但当 `f` 是指向成员的指针时,它会像通过返回 `mem_fn(f)(a…​)` 一样调用它。这使得函数、函数对象和指向成员的指针能够被 `bind_front` 等组件统一处理。

`invoke_r<R>(f, a…​)` 返回 `invoke(f, a…​)`,并转换为 `R`。

示例

struct X
{
    void f(int a, int b) const noexcept;
};

int main()
{
    X x;
    boost::compat::invoke(&X::f, x, 1, 2); // calls x.f(1, 2)
}

提要

namespace boost
{
namespace compat
{

template<class F, class... A> auto invoke(F&& f, A&&... a);

template<class F, class... A> using invoke_result_t = /*...*/;

template<class F, class... A> struct is_invocable;

template<class F, class... A> struct is_nothrow_invocable;

template<class R, class F, class... A> R invoke_r(F&& f, A&&... a);

template<class R, class F, class... A> struct is_invocable_r;

template<class R, class F, class... A> struct is_nothrow_invocable_r;

} // namespace compat
} // namespace boost

invoke

template<class F, class... A> auto invoke(F&& f, A&&... a) noexcept(/*...*/) -> /*...*/;
返回
  • `std::forward<F>(f)(std::forward<A>(a)…​)`,当 `f` 不是指向成员的指针时;

  • `mem_fn(f)(std::forward<A>(a)…​)`,否则。

限制

返回表达式必须有效。

备注

返回类型为 `decltype(r)`,`noexcept` 子句为 `noexcept(noexcept(r))`,其中 `r` 是返回表达式。

invoke_result_t

template<class F, class... A> using invoke_result_t =
  decltype( invoke(std::declval<F>(), std::declval<A>()...) );

is_invocable

template<class F, class... A> struct is_invocable: public /*...*/;

当 `invoke(std::declval<F>(), std::declval<A>()…​)` 是一个有效表达式时,`is_invocable<F, A…​>` 的基类为 `std::true_type`,否则为 `std::false_type`。

is_nothrow_invocable

template<class F, class... A> struct is_nothrow_invocable: public /*...*/;

当 `is_invocable<F, A…​>::value` 为 `false` 时,`is_nothrow_invocable<F, A…​>` 的基类为 `std::false_type`,否则为 `std::integral_constant<bool, noexcept(invoke(std::declval<F>(), std::declval<A>()…​))>`。

invoke_r

template<class R, class F, class... A> R invoke_r(F&& f, A&&... a) noexcept(/*...*/);
返回
  • `static_cast<R>(invoke(std::forward<F>(f), std::forward<A>(a)…​))`,当 `R` 是(可能 cv 限定的)`void` 时;

  • `invoke(std::forward<F>(f), std::forward<A>(a)…​)`,否则,隐式转换为 `R`。

限制

`is_invocable<F, A…​>::value` 必须为 `true`,并且,如果 `R` 不是 cv `void`,则 `std::is_convertible<invoke_result_t<F, A…​>, R>::value` 必须为 `true`。

备注

`noexcept` 子句为 `noexcept(noexcept(static_cast<R>(invoke(std::forward<F>(f), std::forward<A>(a)…​))))`。

is_invocable_r

template<class R, class F, class... A> struct is_invocable: public /*...*/;

当 `invoke_r<R>(std::declval<F>(), std::declval<A>()…​)` 是一个有效表达式时,`is_invocable_r<R, F, A…​>` 的基类为 `std::true_type`,否则为 `std::false_type`。

is_nothrow_invocable_r

template<class R, class F, class... A> struct is_nothrow_invocable: public /*...*/;

当 `is_invocable_r<R, F, A…​>::value` 为 `false` 时,`is_nothrow_invocable<R, F, A…​>` 的基类为 `std::false_type`,否则为 `std::integral_constant<bool, noexcept(invoke_r<R>(std::declval<F>(), std::declval<A>()…​))>`。

<boost/compat/latch.hpp>

描述

头文件 `<boost/compat/latch.hpp>` 以一种可移植的方式实现了 C++20 的 `<latch>` 头文件。

`latch` 是一个一次性屏障,它向下计数,实现一组线程之间的同步。计数器可以手动递减任意值,但递减到零以下会导致未定义行为。指定的等待者最大数量为 `boost::compat::latch::max()`。

示例

std::ptrdiff_t const num_threads = 16;
boost::compat::latch l(num_threads);

std::vector<std::thread> threads;
for (int i = 0; i < num_threads; ++i) {
  threads.emplace_back([&l] {
    // do some preliminary work here...

    // block until all threads have reached this statement
    l.arrive_and_wait();

    // continue with further work...
  });
}

for (auto& t: threads) { t.join(); }

提要

namespace boost
{
namespace compat
{

class latch {
  explicit latch(std::ptrdiff_t expected);

  latch(latch const &) = delete;
  latch &operator=(latch const &) = delete;

  ~latch() = default;

  void count_down(std::ptrdiff_t n = 1);
  bool try_wait() const noexcept;
  void wait() const;
  void arrive_and_wait(std::ptrdiff_t n = 1);

  static constexpr std::ptrdiff_t max() noexcept;
};

} // namespace compat
} // namespace boost

构造函数

计数器构造函数

explicit latch(std::ptrdiff_t expected);
前置条件

expected >= 0 && expected <= boost::compat::latch::max().

效果

构造一个内部计数器值为 `expected` 的 latch。

复制构造函数

latch(latch const &) = delete;

`latch` 不可复制或移动。

成员函数

count_down

void count_down(std::ptrdiff_t n = 1);
前置条件

`n` 不得大于当前内部计数器的值。

效果

将内部计数器减去 `n`。

try_wait

bool try_wait() const noexcept;

返回一个布尔值,指示 latch 的内部计数器是否已达到 0(`true`)或未达到(`false`)。

wait

void wait() const;

阻塞当前线程,直到内部计数器达到 0。

arrive_and_wait

void arrive_and_wait(std::ptrdiff_t n = 1);
前置条件

`n` 不得大于当前内部计数器的值。

效果

将内部计数器减去 `n`,如果计数器非零,则阻塞当前线程。

最大值

static constexpr std::ptrdiff_t max() noexcept;

返回一个表示最大等待者数量的实现定义值。当前为 PTRDIFF_MAX。

<boost/compat/mem_fn.hpp>

描述

头文件 `<boost/compat/mem_fn.hpp>` 实现 C++11 函数 `std::mem_fn`。

`mem_fn(pm)`,其中 `pm` 是指向成员的指针,返回一个函数对象,该函数对象可用于调用成员函数,或使用函数调用语法获取数据成员的引用。

尽管 `std::mem_fn` 是 C++11 的,但后续标准对返回的函数对象提出了更严格的要求(它需要 SFINAE 友好并正确传播 `noexcept`)。`boost::compat::mem_fn` 实现了这些更严格的要求。

示例

struct X
{
    void f(int a, int b) const noexcept;
};

int main()
{
    auto fn = boost::compat::mem_fn(&X::f);

    X x;
    fn(x, 1, 2); // calls x.f(1, 2)
}

提要

namespace boost
{
namespace compat
{

template<class M, class T> auto mem_fn(M T::* pm) noexcept;

} // namespace compat
} // namespace boost

mem_fn

template<class M, class T> auto mem_fn(M T::* pm) noexcept;
返回

函数对象 `fn`,使得

  • `fn(x, a…​)` 等同于 `(x.*pm)(a…​)`,当 `M` 是函数类型且 `X` 的类型为 `T` 或派生自 `T` 时;

  • `fn(x, a…​)` 等同于 `((*x).*pm)(a…​)`,当 `M` 是函数类型且 `X` 的类型不是 `T` 或派生自 `T` 时;

  • `fn(x)` 等同于 `x.*pm`,当 `M` 是对象类型且 `X` 的类型为 `T` 或派生自 `T` 时;

  • `fn(x)` 等同于 `(*x).*pm`,当 `M` 是对象类型且 `X` 的类型不是 `T` 或派生自 `T` 时。

<boost/compat/shared_lock.hpp>

描述

头文件 `<boost/compat/shared_lock.hpp>` 以一种可移植的方式实现了 C++14 的 `std::shared_lock` 类模板。

`shared_lock` 类是一个 RAII 包装器,它管理对提供的 Mutex 的锁定和解锁,前提是该 Mutex 实现 SharedLockable

这是 `unique_lock` 的共享模拟,它调用 `lock_shared()` 而不是 `lock()`。

示例

#include <boost/compat/shared_lock.hpp>

shared_mutex m;

// acquire the lock by calling `m.lock_shared()`
// `m.unlock_shared()` is called automatically for us by `guard` now
boost::compat::shared_lock<shared_mutex> guard(m);
assert(guard.owns_lock());

提要

namespace boost {
namespace compat {

template <class Mutex>
class shared_lock;

template <class Mutex>
void swap( shared_lock<Mutex>& x, shared_lock<Mutex>& y ) noexcept;

template <class Mutex>
class shared_lock {
  using mutex_type = Mutex;

  shared_lock() noexcept = default;
  explicit shared_lock( mutex_type& m );
  shared_lock( mutex_type& m, std::defer_lock_t ) noexcept;
  shared_lock( mutex_type& m, std::try_lock_t );
  shared_lock( mutex_type& m, std::adopt_lock_t );

  ~shared_lock();

  shared_lock( const shared_lock& ) = delete;
  shared_lock& operator=( const shared_lock& ) = delete;

  shared_lock( shared_lock&& u ) noexcept;
  shared_lock& operator=( shared_lock&& u ) noexcept;

  void lock();
  bool try_lock();
  void unlock();

  void swap( shared_lock& u ) noexcept;
  mutex_type* release() noexcept;

  mutex_type* mutex() const noexcept;

  bool owns_lock() const noexcept;
  explicit operator bool() const noexcept;
};

} // namespace compat
} // namespace boost

构造函数

默认构造函数

shared_lock() noexcept = default;
后置条件

`mutex() == nullptr` 且 `owns_lock() == false`。

锁定构造函数

explicit shared_lock( mutex_type& m );
效果

调用 `m.lock_shared()`。

后置条件

`mutex() == std::addressof(m)` 且 `owns_lock() == true`。

延迟构造函数

shared_lock( mutex_type& m, std::defer_lock_t ) noexcept;
后置条件

`mutex() == std::addressof(m)` 且 `owns_lock() == false`。

尝试锁定构造函数

shared_lock( mutex_type& m, std::try_lock_t );
效果

调用 `m.try_lock_shared()`。

后置条件

`mutex() == std::addressof(m)` 且 `owns_lock() == res`,其中 `res` 是 `m.try_lock_shared()` 调用结果。

采纳构造函数

shared_lock( mutex_type& m, std::adopt_lock_t );
前置条件

`m` 必须通过先前对 `m.lock_shared()` 的调用或成功的 `m.try_lock_shared()` 调用来持有。

后置条件

`mutex() == std::addressof(m)` 且 `owns_lock() == true`。

复制构造函数

shared_lock( const shared_lock& ) = delete;

`shared_lock` 不可复制。

移动构造函数

shared_lock( shared_lock&& u ) noexcept;
后置条件

`mutex() == s.mutex()` 且 `owns_lock() == s.owns_lock()`,其中 `s` 是移动前 `u` 的状态。移动后 `u.mutex() == nullptr` 且 `u.owns_lock() == false`。

赋值

复制赋值

shared_lock& operator=( const shared_lock& ) = delete;

`shared_lock` 不可复制。

移动赋值

shared_lock& operator=( shared_lock&& u ) noexcept;
效果

如果 `owns_lock() == true`,则调用 `unlock()`。

后置条件

`mutex() == s.mutex()` 且 `owns_lock() == s.owns_lock()`,其中 `s` 是移动前 `u` 的状态。移动后 `u.mutex() == nullptr` 且 `u.owns_lock() == false`。

析构函数

~shared_lock();
效果

如果 `owns_lock() == true`,则调用 `unlock()`。

成员函数

锁定

lock
void lock();
效果

调用 `mutex()->lock_shared()`。

后置条件

owns_lock() == true.

抛出

`mutex()->lock_shared()` 引起的任何异常。当 `mutex() == nullptr`(带 `std::errc::operation_not_permitted`)或 `owns_lock() == true`(带 `std::errc::resource_deadlock_would_occur`)时为 `std::system_error`。

try_lock
bool try_lock();
效果

调用 `mutex()->try_lock_shared()`。

后置条件

`owns_lock() == res`,其中 `res = mutex()->try_lock_shared()`。

抛出

`mutex()->try_lock_shared()` 引起的任何异常。当 `mutex() == nullptr`(带 `std::errc::operation_not_permitted`)或 `owns_lock() == true`(带 `std::errc::resource_deadlock_would_occur`)时为 `std::system_error`。

unlock
void unlock();
效果

调用 `mutex()->unlock_shared()`。

后置条件

owns_lock() == false.

抛出

如果 `owns_lock() == false`,则为 `std::system_error`(带 `std::errc::operation_not_permitted`)。

修改器

交换
void swap( shared_lock& u ) noexcept;
效果

交换 `*this` 和 `u` 的数据成员。

release
mutex_type* release() noexcept;
后置条件

`mutex() == nullptr` 且 `owns_lock() == false`。

返回

`mutex()` 的先前值。

自由函数 swap
template <class Mutex>
void swap( shared_lock<Mutex>& x, shared_lock<Mutex>& y ) noexcept;
效果

通过 `x.swap(y)` 交换 `x` 和 `y` 的数据成员。

观察器

mutex
mutex_type* mutex() const noexcept;
返回

内部指针的值,为 `nullptr` 或互斥量的地址。

owns_lock
bool owns_lock() const noexcept;
返回

一个布尔值,指示当前 `shared_lock` 实例是否锁定了互斥量。

布尔转换
explicit operator bool() const noexcept;
返回

一个布尔值,指示当前 `shared_lock` 实例是否锁定了互斥量。

<boost/compat/to_array.hpp>

描述

头文件 `<boost/compat/to_array.hpp>` 以一种可移植的方式实现了 C++20 的 `std::to_array` 函数,该函数存在于 `<array>` 头文件中。

`to_array` 从一维 C 数组创建 `std::array`,执行元素逐个复制或移动。

示例

int input [] = {1, 2, 3};
std::array<int, 3> output = boost::compat::to_array(input);
assert((
    output == std::array<int, 3>{{1, 2, 3}}
));

提要

namespace boost
{
namespace compat
{

template <class T, std::size_t N>
constexpr std::array<remove_cv_t<T>, N> to_array(T (&a)[N]);

template <class T, std::size_t N>
constexpr std::array<remove_cv_t<T>, N> to_array(T (&&a)[N]);

} // namespace compat
} // namespace boost

to_array

template <class T, std::size_t N>
constexpr std::array<remove_cv_t<T>, N> to_array(T (&&a)[N]);
效果

通过复制 `a` 中的元素创建 `N` 个元素的数组。对于 `0, …​, N-1` 中的每个 `i`,从 `a[i]` 初始化输出数组中的第 i 个元素。

类型要求

`std::is_constructible_v<remove_cv_t<T>, T&> && !std::is_array_v<T>`。否则,该重载格式错误。

template <class T, std::size_t N>
constexpr std::array<remove_cvref_t<T>, N> to_array(T (&a)[N]);
效果

通过移动 `a` 中的元素创建 `N` 个元素的数组。对于 `0, …​, N-1` 中的每个 `i`,从 `std::move(a[i])` 移动初始化输出数组中的第 i 个元素。

类型要求

`std::is_constructible_v<remove_cv_t<T>, T&&> && !std::is_array_v<T>`。否则,该重载格式错误。

<boost/compat/type_traits.hpp>

描述

头文件 `<boost/compat/type_traits.hpp>` 实现了一些 C++11 之后添加到标准头文件 `<type_traits>` 中的内容。

提要

#include <type_traits>

namespace boost
{
namespace compat
{

template<class T> using remove_const_t = typename std::remove_const<T>::type;

template<class T> using remove_cv_t = typename std::remove_cv<T>::type;

template<class T> using remove_reference_t = typename std::remove_reference<T>::type;

template<class T> using remove_cvref_t = remove_cv_t<remove_reference_t<T>>;

template<class T> using decay_t = typename std::decay<T>::type;

template<bool B, class T = void> using enable_if_t = typename std::enable_if<B, T>::type;

template<bool B, class T, class F> using conditional_t = typename std::conditional<B, T, F>::type;

template<class... T> using void_t = void;


} // namespace compat
} // namespace boost

本文档版权归 2023, 2024 Peter Dimov 及贡献者所有,并根据 Boost Software License, Version 1.0 发布。