久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

C++ std::map 持有任何類型的值

C++ std::map holding ANY type of value(C++ std::map 持有任何類型的值)
本文介紹了C++ std::map 持有任何類型的值的處理方法,對大家解決問題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!

問題描述

限時(shí)送ChatGPT賬號..

基本上我想要 MyClass 持有一個(gè) Hashmap 將字段名稱(字符串)映射到任何類型的值.. 為此,我編寫了一個(gè)單獨(dú)的 MyField 類來保存類型 &價(jià)值信息..

這是我目前所擁有的:

template 類 MyField {T m_Value;int m_Size;}結(jié)構(gòu)我的類{std::map領(lǐng)域;//錯(cuò)誤!!!}

但是正如您所看到的,地圖聲明失敗了,因?yàn)槲覜]有為 MyField 提供類型參數(shù)...

所以我想它必須是這樣的

std::map<字符串,MyField>領(lǐng)域;

std::map<字符串,MyField>領(lǐng)域;


但顯然這破壞了我的整個(gè)目的,因?yàn)槁暶鞯牡貓D只能保存特定類型的 MyField ..我想要一個(gè)可以保存任何類型的 MyField 類的地圖..

有什么辦法可以實(shí)現(xiàn)這個(gè)目標(biāo)嗎?

解決方案

Blindy 的回答很好(+1),但只是為了完成答案:還有另一種方法可以在沒有庫的情況下使用動態(tài)繼承:

class MyFieldInterface{int m_Size;//當(dāng)然在實(shí)際代碼中使用適當(dāng)?shù)脑L問級別...~MyFieldInterface() = 默認(rèn)值;}模板 類 MyField :公共 MyFieldInterface {T m_Value;}結(jié)構(gòu)我的類{std::map領(lǐng)域;}

優(yōu)點(diǎn):

  • 任何 C++ 編碼人員都熟悉它
  • 它不會強(qiáng)迫您使用 Boost(在某些情況下您不允許使用);

缺點(diǎn):

  • 你必須在堆/空閑存儲上分配對象并使用引用語義而不是值語義來操作它們;
  • 以這種方式公開的公共繼承可能會導(dǎo)致過度使用動態(tài)繼承以及許多與類型相關(guān)的長期問題,因?yàn)槟念愋痛_實(shí)過于相互依賴;
  • 如果指針向量必須擁有對象,則它是有問題的,因?yàn)槟仨毠芾礓N毀;

因此,如果可以,請使用 boost::any 或 boost::variant 作為默認(rèn)值,否則僅考慮使用此選項(xiàng).

要解決最后一個(gè)缺點(diǎn),您可以使用智能指針:

struct MyClass {std::map>領(lǐng)域;//或 shared_ptr<>如果您共享所有權(quán)}

但是還有一個(gè)潛在的問題:

它強(qiáng)制您使用 new/delete(或 make_unique/shared)創(chuàng)建對象.這意味著實(shí)際對象是在分配器提供的任何位置(主要是默認(rèn)位置)的空閑存儲(堆)中創(chuàng)建的.因此,由于

然而,如果您需要保持對象插入的順序,這種技術(shù)就會失去興趣.

無論如何,有幾種可能的解決方案,這在很大程度上取決于您的需求.如果您對自己的案例沒有足夠的經(jīng)驗(yàn),我建議您使用我在示例中首先解釋的簡單解決方案或 boost::any/variant.

<小時(shí)>

作為對這個(gè)答案的補(bǔ)充,我想指出非常好的博客文章,這些文章總結(jié)了您可以使用的所有 C++ 類型擦除技術(shù),并附有評論和優(yōu)缺點(diǎn):

  • http://talesofcpp.fusionfenix.com/post-16/episode-9-erasing-the-concrete
  • http://akrzemi1.wordpress.com/2013/11/18/type-erasure-part-i/
  • http://akrzemi1.wordpress.com/2013/12/06/type-erasure-part-ii/
  • http://akrzemi1.wordpress.com/2013/12/11/type-erasure-part-iii/
  • http://akrzemi1.wordpress.com/2014/01/13/type-erasure-part-iv/

Basically I want MyClass that holds a Hashmap that maps Field name(string) to ANY type of Value.. For this purpose I wrote a separate MyField class that holds the type & value information..

This is what I have so far:

template <typename T>
class MyField {
    T m_Value;
    int m_Size;
}


struct MyClass {
    std::map<string, MyField> fields;   //ERROR!!!
}

But as you can see, the map declaration fails because I didn't provide the type parameter for MyField...

So I guess It has to be something like

std::map< string, MyField<int> > fields;

or

std::map< string, MyField<double> > fields;


But obviously this undermines my whole purpose, because the declared map can only hold MyField of a specific type.. I want a map that can hold ANY type of MyField clas..

Is there any way I can achieve this..?

解決方案

Blindy's answer is very good (+1), but just to complete the answer: there is another way to do it with no library, by using dynamic inheritance:

class MyFieldInterface
{
    int m_Size; // of course use appropriate access level in the real code...
    ~MyFieldInterface() = default;
}

template <typename T>
class MyField : public MyFieldInterface {
    T m_Value; 
}


struct MyClass {
    std::map<string, MyFieldInterface* > fields;  
}

Pros:

  • it's familiar to any C++ coder
  • it don't force you to use Boost (in some contexts you are not allowed to);

Cons:

  • you have to allocate the objects on the heap/free store and use reference semantic instead of value semantic to manipulate them;
  • public inheritance exposed that way might lead to over-use of dynamic inheritance and a lot of long-term issues related to your types really being too inter-dependent;
  • a vector of pointers is problematic if it have to own the objects, as you have to manage destruction;

So use boost::any or boost::variant as default if you can, and consider this option only otherwise.

To fix that last cons point you could use smart pointers:

struct MyClass {
    std::map<string, std::unique_ptr<MyFieldInterface> > fields;  // or shared_ptr<> if you are sharing ownership
}

However there is still a potentially more problematic point:

It forces you to create the objects using new/delete (or make_unique/shared). This mean that the actual objects are created in the free store (the heap) at any location provided by the allocator (mostly the default one). Therefore, going though the list of objects very often is not as fast as it could be because of cache misses.

If you are concerned with performance of looping through this list very often as fast as possible (ignore the following if not), then you'd better use either boost::variant (if you already know all the concrete types you will use) OR use some kind of type-erased polymorphic container.

The idea is that the container would manage arrays of objects of the same type, but that still expose the same interface. That interface can be either a concept (using duck-typing techniques) or a dynamic interface (a base class like in my first example). The advantage is that the container will keep same-type objects in separate vectors, so going through them is fast. Only going from one type to another is not.

Here is an example (the images are from there): http://bannalia.blogspot.fr/2014/05/fast-polymorphic-collections.html

However, this technique loose it's interest if you need to keep the order in which the objects are inserted.

In any way, there are several solutions possible, which depends a lot on your needs. If you have not enough experience with your case, I suggest using either the simple solution I first explained in my example or boost::any/variant.


As a complement to this answer, I want to point very good blog articles which summarize all C++ type-erasure techniques you could use, with comments and pros/cons:

  • http://talesofcpp.fusionfenix.com/post-16/episode-nine-erasing-the-concrete
  • http://akrzemi1.wordpress.com/2013/11/18/type-erasure-part-i/
  • http://akrzemi1.wordpress.com/2013/12/06/type-erasure-part-ii/
  • http://akrzemi1.wordpress.com/2013/12/11/type-erasure-part-iii/
  • http://akrzemi1.wordpress.com/2014/01/13/type-erasure-part-iv/

這篇關(guān)于C++ std::map 持有任何類型的值的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!

【網(wǎng)站聲明】本站部分內(nèi)容來源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請聯(lián)系我們刪除處理,感謝您的支持!

相關(guān)文檔推薦

Difference between std::reference_wrapper and simple pointer?(std::reference_wrapper 和簡單指針的區(qū)別?)
Difference between const. pointer and reference?(常量之間的區(qū)別.指針和引用?)
How to access the contents of a vector from a pointer to the vector in C++?(c++ - 如何從指向向量的指針訪問向量的內(nèi)容?)
Meaning of *amp; and **amp; in C++(*amp; 的含義和**amp;在 C++ 中)
Why can#39;t I do polymorphism with normal variables?(為什么我不能對普通變量進(jìn)行多態(tài)?)
Dereferencing deleted pointers always result in an Access Violation?(取消引用已刪除的指針總是會導(dǎo)致訪問沖突?)
主站蜘蛛池模板: 男人天堂999| 亚洲一一在线 | 91麻豆精品国产91久久久更新资源速度超快 | 91精品国产乱码麻豆白嫩 | 91精品综合久久久久久五月天 | 欧美成ee人免费视频 | 亚洲欧美在线观看视频 | 成人免费xxxxx在线视频 | 中文字幕日韩在线观看 | 亚洲精品女人久久久 | 国产一区二区三区久久久久久久久 | 亚洲欧美日韩精品久久亚洲区 | 色又黄又爽网站www久久 | 国产成人精品一区二 | 成人网视频 | 免费国产黄网站在线观看视频 | 亚洲国产精品人人爽夜夜爽 | 视频在线一区二区 | 成人三级av | 久久精品国产亚洲一区二区三区 | 国产精品激情 | 国产欧美精品一区二区三区 | 成年人网站免费 | 国产精品成人在线播放 | 亚洲高清网 | 女同久久另类99精品国产 | 国产一区二区在线视频 | 国产日韩欧美在线观看 | 日韩视频免费在线 | 国产一区二区三区久久久久久久久 | 欧美二区在线 | 在线看一区二区 | 伊人超碰 | 国产精品久久精品 | 欧美精品首页 | 超碰免费在| 国产精品美女久久久久aⅴ国产馆 | 99精品免费久久久久久久久日本 | 91亚洲精选 | 日日操视频 | 亚洲精品国产一区 |