代码之家  ›  专栏  ›  技术社区  ›  schorsch312

我应该什么时候使用std::any

  •  8
  • schorsch312  · 技术社区  · 7 年前

    std::any 介绍。现在可以这样写代码了

    #include <iostream>
    #include <any>
    #include <string>
    
    int main () {
        const double d = 1.2;
        std::any var = d;
        const std::string str = "Hello World";
        var = str;
    }
    

    var 而不是一个 std::string 是分配给它的。

    为什么有 标准::任何

    我认为这违反了法律 least astonishment rule ,因为我觉得很难想到一种情况,在这种情况下,我可以用这个来表达更清楚,我喜欢表达什么。

    是有益的。

    https://gcc.godbolt.org/z/-kepOD

    4 回复  |  直到 7 年前
        1
  •  22
  •   Mayur    7 年前

    何时使用
    void* std::any 增加了类型安全性,这就是为什么它有一些真正的用例。

    一些可能性:

    • 可用类型集。
    • 解析文件-如果您真的无法指定支持的 类型。
    • 消息传递。
    • 与脚本语言绑定。
    • 为脚本语言实现解释器
    • 用户界面-控件可能包含任何内容
    • 编辑器中的实体
      ref
        2
  •  5
  •   bobah    7 年前

    我只能想到动态类型脚本语言的非性能关键型实现来表示脚本世界中的变量,但即使是这样,也有一定的局限性( Boost.Spirit/example/qi/compiler_tutorial

    对于解析器的所有其他内容(例如。 Boost.Spirit.X3 ASIO )通常会有一个更快/更好/更具体的选择,因为很少有事情是真正的“什么”,大多数都比这更具体。

    • std::variant 和/或 std::optional “几乎任何价值”
    • std::packaged_task / std::function +lambdas表示“带参数的回调”,这将是 void* 在C API中。
    • 等。

    无效* may allocate 堆上的内存,这对于高性能代码来说是致命的。

        3
  •  4
  •   Yakk - Adam Nevraumont    7 年前

    std::any 是一个 词汇 类型。当你需要存储一些东西的时候,你可以使用它。

    它有许多“一级”用途:

    1. 当与本身就有这种类型的脚本语言交互时,这是一种自然的匹配。

    2. 当您有一个具有高度多态性内容的属性树,并且树的结构与树的生产者和消费者分离时。

    3. 当更换相当于 void* 通过中间层传递的数据块,中间层实际上并不关心它所承载的内容。

    在其他情况下,它也可以用作构建块。例如, std::function 可以选择将其值存储在 :

    template<class R, class...Args>
    struct func<R(Args...)> {
      mutable std::any state;
      R(*f)(std::any& state, Args&&...) = nullptr;
      template<class T>
      void bind(T&& t) {
        state = std::forward<T>(t);
        f = [](std::any& state, Args&&...args)->R {
          return std::any_cast<T&>(state)(std::forward<Args>(args)...);
        };
      }
      R operator()(Args...args)const {
        return f(state, std::forward<Args>(args)...);
      }
    };
    

    这是一个相当小的实现(大部分) . 基本上我用过 any 键入擦除复制/移动/销毁。

    您可以在其他地方使用此选项来解决类似的问题(您正在键入擦除某些操作,并且还希望键入擦除复制/移动/销毁),或者 generalize it .

        4
  •  1
  •   Caleth    7 年前