[英]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
是有益的。
何時使用
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*
的情況。 std::any
是一種詞匯類型。 當您需要存儲一些東西時,您可以使用它作為值。
它有許多“第一級”用途:
當與本身具有此類類型的腳本語言進行交互時,這是一種自然的搭配。
當您擁有一棵具有高度多態內容的屬性樹,並且樹的結構與樹的生產者和消費者解耦時。
當替換通過中間層的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.