自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

從 void 到 std::any:現(xiàn)代 C++ 類型系統(tǒng)的進(jìn)化之路

開發(fā)
想象一下,你是一位魔法師,口袋里有個神奇的百寶箱,不管是數(shù)字、字符串、還是你自己發(fā)明的各種稀奇古怪的類型,統(tǒng)統(tǒng)都能往里面塞!這不就是我們今天要認(rèn)識的新朋友std::any 嘛。

嘿嘿!親愛的碼農(nóng)小伙伴們 ?? ,今天咱們要一起探索一個超級炫酷的 C++17 新特性 -std::any ??!

想象一下,你是一位魔法師 ??♂?,口袋里有個神奇的百寶箱 ??,不管是數(shù)字 ??、字符串 ??、還是你自己發(fā)明的各種稀奇古怪的類型 ??,統(tǒng)統(tǒng)都能往里面塞!這不就是我們今天要認(rèn)識的新朋友std::any 嘛~ 它就像是代碼世界里的哆啦A夢口袋 ??,百變又神奇!

為什么需要 std::any?

我們先來聊聊在 C++17 之前,我們是怎么處理"存儲任意類型數(shù)據(jù)"這個讓人頭疼的問題的~

想象一下,你是個魔法師學(xué)徒 ??♂?,需要一個百寶袋來存放各種神奇的物品。但是在 C++17 之前,我們只有一些不太完美的選擇...

首先,我們試過用void* 指針這個調(diào)皮的小家伙 ??:

void* data = nullptr;
data = new int(42);       // 往袋子里放個數(shù)字
data = new std::string(); // 再放個字符串

哎呀呀~這個方法就像是蒙著眼睛往袋子里塞東西 ??,不僅容易摔跤(類型不安全),還得自己記得打掃衛(wèi)生(手動管理內(nèi)存)。多不優(yōu)雅呀!

那要不試試聯(lián)合體(union)?這個小機(jī)靈鬼看起來挺不錯的 ??:

union Data {
    int n;
    float f;
    char str[20];
};

但是等等!這個小家伙有點挑食呢 ?? —— 它只喜歡簡單的類型,遇到std::string 這樣的復(fù)雜類型就搖頭說"不要不要"了~

那繼承體系呢?讓所有物品都繼承自一個基類 ??:

class Base { 
    virtual ~Base() = default; 
};
class Derived : public Base { /*...*/ };
std::vector<Base*> items;

嗯...這就像是要求所有的魔法物品都得先去魔法學(xué)校注冊一樣 ??,太麻煩啦!而且還得處理各種類型轉(zhuǎn)換,就像給每個物品都貼上標(biāo)簽一樣繁瑣~

但是!現(xiàn)在我們有了std::any 這個超級百寶箱 ?!它就像是哆啦A夢的四次元口袋一樣神奇:

  • 想放什么類型就放什么類型 ??
  • 不用擔(dān)心內(nèi)存泄漏 ??
  • 類型安全又可靠 ???
  • 使用起來簡單又方便 ??

讓我們繼續(xù)往下看,看看這個神奇的百寶箱要怎么用吧!??

基礎(chǔ)用法

來來來,讓我們一起召喚出這個超級神奇的魔法百寶箱吧!??? 就像打開哆啦A夢的四次元口袋一樣令人期待呢~

#include <any>
#include <iostream>

int main() {
    std::any magicBox;    // 噠噠!變出一個百寶箱 ??
    
    magicBox = 42;        // 哇!塞進(jìn)去一個神秘數(shù)字 ??
    magicBox = "魔法咒語"; // 嘿咻!變成了一串神秘咒語 ?
    magicBox = 3.14159;   // 噗!又變成圓周率啦 ??
    
    // 讓我們念個咒語,看看能變出什么來~
    if (magicBox.has_value()) {  // 先偷偷看看盒子里有沒有東西 ??
        // 先確認(rèn)一下類型是否匹配 ??
        if (magicBox.type() == typeid(double)) {
            double value = std::any_cast<double>(magicBox);
            std::cout << "變變變,出來吧!? " << value << std::endl;
        } else {
            std::cout << "咦?這不是我要的類型呢~ ??" << std::endl;
        }
    }
}

哇哦!看到了嗎?這個神奇的百寶箱簡直就像是會魔法一樣呢!?? 它就像是一個調(diào)皮的變色龍 ??,可以隨心所欲地變成任何類型。今天是個活潑的整數(shù) ??,明天可能就搖身一變成了優(yōu)雅的字符串 ??,后天說不定又變成了神秘的浮點數(shù) ?? 呢!

我們用type() 和typeid 來檢查類型,就像是用魔法鏡子 ?? 先看看盒子里裝的是什么,確認(rèn)無誤后再打開,這樣就不會有意外啦!而has_value() 就像是偷偷掀開盒子的一角,看看里面是不是真的藏著寶貝 ??。

是不是感覺編程也可以這么有趣呀?就像在魔法學(xué)校上課一樣,每天都能學(xué)到新的咒語,創(chuàng)造出更多神奇的魔法!? 快來試試這個百變魔法盒吧~ ????

實戰(zhàn)示例:打造魔法世界的背包系統(tǒng) ??

嘿嘿,小伙伴們!既然我們已經(jīng)掌握了std::any 這個神奇的魔法 ?,不如來點更有趣的?讓我們一起打造一個超級可愛的游戲背包系統(tǒng)吧!想象你是個小魔法師 ??♂?,口袋里裝著各種神奇的道具...

首先,我們需要一些有趣的道具類型,就像在魔法商店里挑選寶貝一樣 ??:

#include <any>
#include <string>
#include <vector>
#include <iostream>

// 先來幾個有趣的道具類型 ??
struct Weapon { 
    std::string name;
    int damage;
};

struct Potion {
    std::string color;
    int healing;
};

struct Coin {
    int value;
};

看看這些可愛的道具!我們有威力十足的武器 ??、神奇的藥水 ??,還有閃閃發(fā)光的金幣 ??!每個道具都有自己的特點,就像魔法世界里的寶貝一樣~

接下來,讓我們創(chuàng)造一個神奇的背包來裝這些寶貝 ??:

class MagicBag {
    std::vector<std::any> items;  // 這就是我們的魔法背包啦!??
public:
    // 往背包里塞東西,就像變魔術(shù)一樣簡單!?
    void addItem(const std::any& item) {
        items.push_back(item);
        std::cout << "哇!背包里多了個神秘物品!" << std::endl;
    }
}

瞧瞧這個可愛的背包!它就像哆啦A夢的四次元口袋一樣,什么都能裝進(jìn)去 ??。每次添加物品的時候,背包都會開心地告訴我們:"哇!又有新寶貝啦!" ??

但是等等,我們怎么知道背包里裝了什么呢?來看看這個神奇的探索功能 ??:

    void inspectBag() {
        std::cout << "讓我們看看魔法背包里有什么~ ??" << std::endl;
        for (const auto& item : items) {
            if (item.type() == typeid(Weapon)) {
                auto& weapon = std::any_cast<const Weapon&>(item);
                std::cout << "發(fā)現(xiàn)一把武器:" << weapon.name 
                         << ",傷害值:" << weapon.damage << " ??" << std::endl;
            }
            // ... 其他類型的檢查 ...
        }
    }
};

哇哦!這就像是在玩尋寶游戲一樣呢 ???!每次查看背包,我們都能知道里面藏著什么寶貝。是威力強大的武器?還是神奇的藥水?亦或是閃閃發(fā)光的金幣?就讓我們來試試這個神奇的背包吧 ?:

int main() {
    MagicBag bag;  // 創(chuàng)建一個魔法背包 ?
    
    // 往背包里放些寶貝吧!
    bag.addItem(Weapon{"火焰劍", 100});         // 放入一把超酷的武器 ??
    bag.addItem(Potion{"藍(lán)色", 50});           // 來點神奇藥水 ??
    bag.addItem(Coin{1000});                   // 當(dāng)然要帶上金幣啦 ??
    
    bag.inspectBag();  // 讓我們看看背包里都有什么呀~
    return 0;
}

是不是感覺特別有趣呀??? 通過這個可愛的背包系統(tǒng),我們不僅學(xué)會了如何使用std::any,還體會到了編程的樂趣!就像在魔法世界里探險一樣,每一行代碼都充滿了驚喜和期待 ??

記住哦,雖然這只是個簡單的例子,但它完美展示了std::any 的神奇之處。在實際開發(fā)中,我們可能需要更復(fù)雜的系統(tǒng),但基本原理就是這么簡單又有趣!現(xiàn)在,快拿起你的魔法棒,創(chuàng)造屬于你的魔法背包吧!???

std::any 的高級特性

哎呀,小伙伴們!我們的魔法百寶箱std::any 還藏著好多有趣的小機(jī)關(guān)呢!?? 讓我們一起來探索這些神奇的魔法吧~

首先,我們來看看怎么確認(rèn)百寶箱里是不是真的藏著寶貝 ??:

std::any treasureBox;  // 創(chuàng)建一個神奇的百寶箱 ?
std::cout << "百寶箱是空的嗎?" << (!treasureBox.has_value() ? "是呀是呀~" : "里面有寶貝哦!") << std::endl;

treasureBox = 42;  // 往里面放個幸運數(shù)字 ??
std::cout << "現(xiàn)在百寶箱里有寶貝啦!" << (treasureBox.has_value() ? "沒錯!" : "咦?怎么不見了?") << std::endl;

哇!has_value() 就像是個調(diào)皮的小精靈 ??♀?,幫我們偷偷看看盒子里是不是藏著寶貝呢!

那要是想把寶貝拿出來該怎么辦呢?來看看這個神奇的咒語 ??:

treasureBox = "魔法水晶球";  // 放入一個水晶球 ??

// 在取出寶貝前,先確認(rèn)一下類型是否正確 ??
if (treasureBox.type() == typeid(int)) {
    // 類型匹配,可以安全取出
    int value = std::any_cast<int>(treasureBox);
    std::cout << "成功取出數(shù)字:" << value << " ?" << std::endl;
} else {
    std::cout << "哎呀呀~這不是我們要的類型呢!要用對咒語才行哦~ ??" << std::endl;
}

看到了嗎?我們先用type() 檢查類型是否匹配,這樣就不會出現(xiàn)意外啦!這就像是在打開百寶箱前,先用魔法鏡子看看里面裝的是什么 ??

還有一個超級厲害的技能,我們可以直接問問盒子里裝的是什么類型的寶貝 ??:

treasureBox = 3.14159;  // 放入圓周率 ??
std::cout << "讓我猜猜盒子里是什么類型的寶貝~" << std::endl;
std::cout << "是不是浮點數(shù)呢?" << (treasureBox.type() == typeid(double) ? "猜對啦!??" : "猜錯啦!??") << std

type() 就像是個誠實的小助手 ??,總是會告訴我們盒子里到底藏著什么類型的寶貝~

最后還有一個神奇的重置魔法,可以讓盒子恢復(fù)到空空如也的狀態(tài) ?:

treasureBox.reset();  // 施展重置魔法!
std::cout << "盒子被清空啦~" << (!treasureBox.has_value() ? "果然是空的!??" : "咦?還有東西???") << std::endl;

reset() 就像是一個清理咒語 ??,可以讓魔法盒子重新煥然一新,準(zhǔn)備裝入新的寶貝!

是不是感覺std::any 越來越有趣了呢?它就像是一個會變魔術(shù)的小盒子 ??,不僅能裝各種各樣的寶貝,還能告訴我們里面藏著什么。記得在使用的時候要先檢查類型是否匹配,這樣就不會遇到意外啦!?

記住哦,魔法雖然強大,但也要小心使用~畢竟每次施法都需要消耗一些魔力值(性能開銷)呢!?? 下次遇到需要存儲不同類型數(shù)據(jù)的場景,就可以想起這個神奇的百寶箱啦!??

使用注意事項

嘿!親愛的魔法師朋友們 ??♂?,在你開始瘋狂使用這個神奇的std::any 百寶箱之前,讓我們來聊聊幾個使用魔法時需要注意的小秘密吧!??

你知道嗎?每次使用std::any 的魔法都需要消耗一些魔力值(也就是運行時開銷)哦!這里說的"魔力值"其實就是程序運行時的性能開銷,主要包括:

  • 內(nèi)存開銷:std::any 需要在堆上動態(tài)分配內(nèi)存來存儲數(shù)據(jù) ??
  • 類型擦除開銷:它需要額外的機(jī)制來記住和管理存儲的類型信息 ??
  • 類型檢查開銷:每次取值時都需要進(jìn)行運行時的類型檢查 ??
  • 復(fù)制開銷:在存儲和提取值時可能產(chǎn)生額外的對象復(fù)制 ??

就像是在玩魔法游戲時要留意魔力條一樣 ??。所以呀,不要太貪心,不是所有東西都要往百寶箱里塞哦!來看個例子:

std::vector<std::any> inventory;  // 這是我們的百寶箱 ??
// 不推薦這樣頻繁使用
for (int i = 0; i < 10000; i++) {
    inventory.push_back(std::any(i));  // 每次都消耗魔力值!??
}

哎呀呀,這樣會消耗好多魔力值呢!如果你知道只會存儲數(shù)字,那還是乖乖用std::vector<int> 吧!??

還有啊,每次從百寶箱里取東西的時候,一定要像個細(xì)心的魔法師一樣,先確認(rèn)類型是否正確哦!不然可能會被std::bad_any_cast 這個調(diào)皮的小精靈搗亂呢!??

std::any magicBox = "魔法藥水";  // 放入一瓶藥水 ??
try {
    int number = std::any_cast<int>(magicBox);  // 糟糕!類型不對!??
} catch (const std::bad_any_cast& e) {
    std::cout << "哎呀~搞錯啦!這不是數(shù)字而是藥水呢!??" << std::endl;
}

誒,對了!如果你已經(jīng)知道你的百寶箱里只會放特定的幾樣寶貝,比如只放武器??、藥水??和金幣??,那么使用std::variant 這個更專業(yè)的魔法容器可能會更好哦!它就像是一個定制版的百寶箱,更安全也更節(jié)省魔力值呢!

std::variant<Weapon, Potion, Coin> specialBox;  // 專門的百寶箱 ?
specialBox = Weapon{"火焰劍", 100};  // 完美契合!??

記住啦,魔法雖然強大,但也要適可而止。就像吃糖果一樣,吃太多可是會蛀牙的哦!?? 選擇合適的魔法工具,讓你的代碼既優(yōu)雅又高效,這才是一個真正的代碼魔法師呢!?

讓我們一起成為既會用魔法,又懂得節(jié)制的智慧魔法師吧!???

相關(guān)類型對比

嘿嘿,小伙伴們!既然我們已經(jīng)認(rèn)識了神奇的std::any ??,不如來認(rèn)識認(rèn)識它的親戚們吧!就像魔法世界里的大家庭一樣,每個成員都有自己的獨特魔法呢~ ?

首先來認(rèn)識一下std::variant 這位帥氣的表哥 ??:

std::variant<int, std::string, double> magicBox;  // 這個盒子只能放特定的寶貝哦!
magicBox = 42;        // 放個數(shù)字進(jìn)去 ??
magicBox = "魔法咒語";  // 變成字符串啦 ??

看到了嗎?std::variant 就像是個挑剔的魔法盒子,它可不是隨隨便便什么東西都往里塞的!它要提前說好能放什么類型,但正因為這樣,它比std::any 更安全也更節(jié)省魔力值呢!??

接下來是可愛的表妹std::optional ??:

std::optional<std::string> maybeSpell;  // 可能有魔法咒語,也可能沒有~
if (!maybeSpell.has_value()) {
    std::cout << "哎呀,魔法咒語不見啦!??" << std::endl;
}
maybeSpell = "阿拉霍洞開";  // 找到咒語啦!?

這個小可愛特別適合處理那些"可能有,可能沒有"的情況,就像薛定諤的貓一樣神奇呢!??

最后是功能強大的堂哥std::function ??:

std::function<int(int, int)> magicSpell;  // 這是一個神奇的魔法函數(shù)!
magicSpell = [](int a, int b) { return a + b; };  // 設(shè)置加法魔法 ?
std::cout << "魔法計算:" << magicSpell(10, 20) << " ?" << std::endl;

這位堂哥可厲害啦!他能把各種各樣的函數(shù)、lambda 表達(dá)式都裝進(jìn)去,就像是個百變的魔法師傅!??♂?

記住哦,每個魔法工具都有它最擅長的領(lǐng)域:

  • 想要百變自由?找std::any ??
  • 需要類型安全?選std::variant ???
  • 處理可能為空的值?用std::optional ??
  • 包裝各種函數(shù)?用std::function ??

就像魔法世界里的法術(shù)一樣,選對了工具,寫代碼也能變得充滿樂趣呢!現(xiàn)在,快拿起你的魔法棒,去創(chuàng)造屬于你的魔法程序吧!???

責(zé)任編輯:趙寧寧 來源: everystep
相關(guān)推薦

2024-10-14 15:04:15

C++std::any存儲

2023-10-04 00:38:30

C++原子

2024-02-26 00:05:00

C++開發(fā)

2010-01-21 16:08:26

C++語言

2023-12-13 10:08:59

C++原子代碼

2024-02-04 09:13:24

基礎(chǔ)設(shè)施代碼DevOps

2024-09-26 10:29:56

數(shù)據(jù)中臺數(shù)據(jù)飛輪

2024-03-05 10:34:33

KubernetesPod云原生

2010-02-06 09:53:26

C++ void

2011-07-13 17:42:32

CC++

2011-07-13 17:08:02

CC++

2011-07-13 16:48:55

CC++

2023-01-04 11:04:32

2015-06-25 11:21:33

C++Objective-C

2021-12-06 23:00:36

CC++編程語言

2016-10-20 16:07:11

C++Modern C++異步

2024-12-26 08:00:38

2010-02-06 09:59:54

C++ void使用規(guī)

2023-10-25 13:27:20

C++字符串

2023-01-01 14:22:17

點贊
收藏

51CTO技術(shù)棧公眾號