簡體   English   中英

我什么時候應該使用 std::any

[英]When should I use std::any

由於引入了 C++17 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;
}

一個 double 被分配給變量var而不是一個std::string被分配給它。

為什么引入std::any

我認為這違反了least astonishment rule ,因為我發現很難想到一種情況,可以用它來更清楚地表達我喜歡表達的東西。

有人可以舉一個很好的例子,當std::any是有益的。

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

何時使用
void*作為具有一些有限用例的極其不安全的模式, std::any增加了類型安全性,這就是為什么它有一些實際用例。

一些可能性:

  • 在庫中 - 當庫類型必須在不知道可用類型集的情況下保存或傳遞任何內容時。
  • 解析文件 - 如果您確實無法指定支持的類​​型。
  • 消息傳遞。
  • 與腳本語言的綁定。
  • 為腳本語言實現解釋器
  • 用戶界面 - 控件可能包含任何內容
  • 編輯器中的實體
    參考

我將其總結為經典的“當你無法避免時使用它”。

我只能想到動態類型腳本語言的非性能關鍵實現來表示來自腳本世界的變量,但即使如此( Boost.Spirit/example/qi/compiler_tutorial沒有這樣做,對於解析器和運行)。

對於從解析器(例如Boost.Spirit.X3 )到庫 API(例如ASIO )的所有其他內容,通常會有更快/更好/更具體的替代方案,因為很少有東西是真正的“任何東西”,大多數都比這更具體.

  • std::variant和/或std::optional用於“幾乎任何值”
  • std::packaged_task / std::function + lambdas 用於“帶參數的回調”,這將是 C API 中void*的情況。
  • 等等。

具體來說,我不會盲目地將它插入作為void*的替代品,因為它可能會在堆上分配內存,這對於高性能代碼來說可能是致命的。

std::any是一種詞匯類型。 當您需要存儲一些東西時,您可以使用它作為值。

它有許多“第一級”用途:

  1. 當與本身具有此類類型的腳本語言進行交互時,這是一種自然的搭配。

  2. 當您擁有一棵具有高度多態內容的屬性樹,並且樹的結構與樹的生產者和消費者解耦時。

  3. 當替換通過中間層的void*數據塊時,中間層實際上並不關心它攜帶的是什么。

在其他情況下,它也可以用作構建塊。 例如, std::function可以選擇將其值存儲在std::any

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)...);
  }
};

這是(大部分) std::function一個非常小的實現。 基本上我已經使用any來鍵入擦除復制/移動/銷毀。

您可以在其他地方使用它來解決類似的問題(您正在對某些操作進行類型擦除,並且還想輸入擦除復制/移動/銷毀),或者對其進行概括

它在 Wt 中使用,為表格數據提供非模板接口。

內置和 Wt 類型有到字符串的轉換,您可以通過專門化Wt::any_traits來注冊額外的轉換。 這允許將任何內容顯示為表中的條目,視圖類不必知道有關它們顯示的類型的任何信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM