C++ 面试题 目录

C++ 中如何使用 std::any 或 std::variant 实现类型擦除?

推荐答案

在 C++ 中,std::anystd::variant 都可以用于实现类型擦除,但它们的使用场景和方式有所不同。

使用 std::any 实现类型擦除

std::any 是一个可以存储任意类型值的容器。它通过类型擦除机制,允许你在运行时存储和检索不同类型的值。

-- -------------------- ---- -------
-------- -----
-------- ----------
-------- --------

--- ------ -
    -------- -----

    ---- - --- -- ------
    --------- -- ------- ---- - -- ------------------------ -- ----------

    ---- - ------------------- --------- -- -------
    --------- -- ------- ------- - -- -------------------------------- -- ----------

    ------ --
-

使用 std::variant 实现类型擦除

std::variant 是一个类型安全的联合体,它可以存储一组预定义类型中的任意一个。与 std::any 不同,std::variant 需要在编译时指定可能的类型。

-- -------------------- ---- -------
-------- ---------
-------- ----------
-------- --------

--- ------ -
    ----------------- ------------ -----

    ---- - --- -- ------
    --------- -- ------- ---- - -- ------------------- -- ----------

    ---- - ------------------- --------- -- -------
    --------- -- ------- ------- - -- --------------------------- -- ----------

    ------ --
-

本题详细解读

std::any 的详细解读

std::any 是 C++17 引入的一个标准库类型,用于存储任意类型的值。它的主要特点是:

  • 类型擦除std::any 可以存储任何类型的值,而不需要在编译时知道具体的类型。
  • 类型安全:当你尝试从 std::any 中提取值时,如果类型不匹配,会抛出 std::bad_any_cast 异常。
  • 性能开销:由于 std::any 需要在运行时进行类型检查和转换,因此它可能比 std::variant 有更高的性能开销。

std::variant 的详细解读

std::variant 是 C++17 引入的另一个标准库类型,用于存储一组预定义类型中的任意一个。它的主要特点是:

  • 类型安全std::variant 在编译时就知道所有可能的类型,因此它比 std::any 更类型安全。
  • 性能:由于 std::variant 在编译时就知道所有可能的类型,因此它的性能通常比 std::any 更好。
  • 访问方式:你可以使用 std::getstd::visit 来访问 std::variant 中存储的值。

选择 std::any 还是 std::variant

  • 使用 std::any:当你需要在运行时存储任意类型的值,并且无法在编译时确定所有可能的类型时,std::any 是一个不错的选择。
  • 使用 std::variant:当你知道所有可能的类型,并且希望在编译时进行类型检查时,std::variant 是更好的选择。

通过理解 std::anystd::variant 的特点和适用场景,你可以在 C++ 中更灵活地实现类型擦除。

纠错
反馈