Mapping Types to Values (in C++) (2024)

The idea of a type map is quite simple. It's similar to a hash table, except its keys are types. It has two basic operations - associate a value with the given type and retrieve the value associated with the given type. So, how would one go about implementing something like this in C++? Let's find out.

Compile-Time Solution

The most simple and straightforward way of associating a value with a type is simply introducing a static member variable into your class. It's not very flexible, though. You can get a bit more fancy. For example, if you want to be able to provide a string annotation for arbitrary types, you can do it with the help of template specializations:

template <typename T>struct StringAnnotationTypeMap { static const std::string annotation; };template <typename T>const std::string StringAnnotationTypeMap<T>::annotation = "default value";template <>const std::string StringAnnotationTypeMap<int>::annotation = "annotation for int";//etc...

The idea here is that you simply specialize the template for any types you want to put in your typemap.

You can then use the type map like this:

std::cout << StringAnnotationTypeMap<int>::annotation << "\n";

Runtime Typemaps

The above solution works, but I happen to think that initializing the type map in this way is a pain. More importantly, it's fundamentally impossible to use if you require multiple instances of type maps that can be created and destroyed arbitrarily at runtime. What we have above, one could say, is a "static" or "compile time" type map: your program can't create and populate a new typemaps when it's running. But why would we want to do that anyway? Let's consider the following example.

A Motivating Example

In game development, there is a pattern called "Entity Component System". In a nutshell, the idea of ECS is that all the entities in the game (such as enemies, power-ups, projectiles, etc.) are modelled as being composed of various "components" rather than being members of a giant class hierarchy. Various "systems" (such as AI system, graphics system, etc.) then read or manipulate the state of components to achieve the desired effects.

For example, in a 2D side scrolling game, the player's character might be an entity that has (among others) a sprite component (for displaying the animation of the player on screen) and a physics component (for detecting collisions). On the other hand, something like a butterfly that just flies around for decoration, might have a sprite component, but no physics component (since it doesn't collide with anything). The graphics system can use the sprite component to draw a graphical representation of an entity on the screen. On the other hand, the AI system may change the sprite component of a computer-controlled character's entity in order to display a different image depending on whether the character is walking or standing still. Note how this approach is different from, say, having an entity class that extends the "PhysicsEntity" and "Drawable" classes.

Entity Component System is an interesting pattern, but a complete discussion on it is not within the scope of this post (read this if you want to know more about ECS). For now, we'll focus on just one aspect: simplifying the process of adding new component types.

Let's say you just created a new type of component called HitPointComponent, which has the amount of hit points, or "health" that a character has left:

class HitPointComponent : public AbstractComponent {public: void takeHitFrom(const Entity *other_entity); void add(int hp); void setCurrentCap(int c); private: int m_hitPoints; // amount of hitpoints, can't be greater than m_currentCap int m_currentCap; // maximum amount of hitpoints};

It would be nice to be able say: "hey, entity e1, give me your HitPointComponent" without having to write any additional code. You can achieve that by simply having Entity contain a hash table that maps strings (component names) to AbstractComponent pointers:

class Entity {public:// ... AbstractComponent* get (const std::string &component_name) { auto it = m_components.find(component_name); assert(it != m_components.end()); return it->second.get(); }private: std::unordered_map<std::string, std::unique_ptr<AbstractComponent>> m_components;//...};

It's simple to implement, but also not very safe: there are no guarantees that the component obtained using e->get("HitPointComponent"); is actually a HitPointComponent. Also, every time you want to do something with a component, you have to deal with this awkward cast: dynamic_cast<HitPointComponent>(player->get("HitPointComponent"))->takeHitFrom(projectile).

We can use dynamic type maps for a safer and more convenient solution. It will be possible to write code like this:

auto e = std::make_unique<Entity>();e->provideComponent<HitPointComponent>(std::make_unique<HitPointComponent>());//...e->get<HitPointComponent>()->takeHitFrom(projectile);

Mapping Types To Integers

First, we need an efficient way to obtain a unique identifier (that can be used at runtime) for a given type. Of course, typeid comes to mind. typeid(HitPointComponent) refers to a object of type const std::type_info. Conveniently, const std::type_info has a method called hash_code, which appears to be doing what we want - it returns an integer corresponding to our type!

So then, we're done, right? Well, not quite. Unfortunately, the C++ standard does not strictly require that method to return different values for different types. It merely suggests that the compiler developers should try to implement hash_code in a way that returns different values for different types. However, it is not a strict requirement. The only strict requirement is returning same values for same types.

In practice, most implementations of std::type_info::hash_code probably do return different values for different types. But maybe you don't like to put too much trust into that (or maybe you just don't want to use RTTI). You can use the following trick:

// In a header file:#include <atomic>extern std::atomic_int TypeIdCounter;template <typename T>int getTypeId() { static int id = ++TypeIdCounter; return id;}// In a *.cpp file:std::atomic_int TypeIdCounter(0);

A call to getTypeId() will return a unique integer for your type. The trick relies on the fact that getTypeId() and getTypeId() are considered two completely different functions (even though they are instantiated from the same function template), and therefore they will have completely different static variables id initialized to different values. The concrete values will depend on what the value of the global TypeIdCounter was at the time of the function call. TypeIdCounter is made atomic just in case getTypeId is called from different threads, but you can get away with just a plaint int if you program is single-threaded.

Implementing Our Type Map

Using the above technique, it's quite easy to implement a type map by first converting the type to the corresponding integer and then using that integer as a key into a hash map. We'll write a class template, TypeMap, with a single template parameter, ValueType. It will map arbitrary types to objects of type ValueType.

#include <unordered_map>#include <atomic>template <class ValueType>class TypeMap { // Internally, we'll use a hash table to store mapping from type // IDs to the values. typedef std::unordered_map<int, ValueType> InternalMap;public: typedef typename InternalMap::iterator iterator; typedef typename InternalMap::const_iterator const_iterator; typedef typename InternalMap::value_type value_type; const_iterator begin() const { return m_map.begin(); } const_iterator end() const { return m_map.end(); } iterator begin() { return m_map.begin(); } iterator end() { return m_map.end(); } // Finds the value associated with the type "Key" in the type map. template <class Key> iterator find() { return m_map.find(getTypeId<Key>()); } // Same as above, const version template <class Key> const_iterator find() const { return m_map.find(getTypeId<Key>()); } // Associates a value with the type "Key" template <class Key> void put(ValueType &&value) { m_map[getTypeId<Key>()] = std::forward<ValueType>(value); } private: template <class Key> inline static int getTypeId() { static const int id = LastTypeId++; return id; } static std::atomic_int LastTypeId; InternalMap m_map;};template <class ValueType>std::atomic_int TypeMap<ValueType>::LastTypeId(0);

With this, we can do stuff like:

TypeMap<std::string> tmap;tmap.put<int>("integers!");tmap.put<double>("doubles!");std::cout << tmap.find<int>()->second << "\n";

Using Our Type Map

The following demonstrates how to use the TypeMap class template in our Entity class:

class Entity {public:// ... template <typename Component> Component* get() { auto it = m_components.find<Component>(); assert(it != m_components.end()); return static_cast<Component*>(it->second.get()); } template <typename Component> void provideComponent(std::unique_ptr<Component> &&c) { m_components.put<Component>(std::forward<std::unique_ptr<Component>>(c)); }private: TypeMap<std::unique_ptr<AbstractComponent>> m_components;//...};

Conclusion

You won't have to use this technique often (if at all), but I thought it was pretty neat and worth sharing.

Like this post? Follow this blog on Twitter for more!

Mapping Types to Values (in C++) (2024)

FAQs

How many types of maps are there in C++? ›

As of C++11, there are two1 map types in C++. std::map is based on a binary tree, and std::unordered_map is based on a hash table.

What is map data type in C++? ›

A C++ map is a way to store a key-value pair. A map can be declared as follows: #include <iostream> #include <map> map<int, int> sample_map; Each map entry consists of a pair: a key and a value.

Can a C++ map have multiple values? ›

The C++ STL map is an associative map between a single key and a single value. In addition, the key must be unique for the given map. The C++ STL also provides a multimap template, which removes the unique key restriction. A single key in a multimap can map to multiple values.

Is there a Hashmap in C++? ›

Simple Hash Map (Hash Table) Implementation in C++ Hash table (also, hash map) is a data structure that basically maps keys to values. A hash table uses a hash function to compute an index into an array of buckets or slots, from which the corresponding value can be found.

What are the 4 types of map data? ›

According to the ICSM (Intergovernmental Committee on Surveying and Mapping), there are five different types of maps: General Reference, Topographical, Thematic, Navigation Charts and Cadastral Maps and Plans.

What is data mapping with example? ›

For example, the state field in a source system may show Illinois as "Illinois," but the destination may store it as "IL." Data mapping bridges the differences between two systems, or data models, so that when data is moved from a source, it is accurate and usable at the destination.

What type of data is maps? ›

Fundamentally, maps display only two types of data: qualitative and quantitative. Qualitative data differentiates between various types of things. Quantitative data communicates a message of magnitude.

Can a map have three values C++? ›

You cannot have three elements. The STL map stores a key-value pair.

How are values stored in map C++? ›

Maps are associative containers that store elements in a combination of key values and mapped values that follow a specific order. No two mapped values can have the same key values. In C++, maps store the key values in ascending order by default. A visual representation of a C++ map.

How do I put multiple values on a map? ›

If this is an application requirement, the three best ways to solve the 'multiple values per key in a map in Java' problem are: Stick with the standard APIs and add a collection class like a 'Vector' or 'ArrayList' to your map or set. Use the MultiMap and MultiValueMap classes from the Apache Commons library.

Does C++ have Arraylist? ›

C++ allows us a facility to create an array of lists. An array of lists is an array in which each element is a list on its own.

Is map an array C++? ›

Map is an associative container/array that store the elements as a combination of key-value pairs (just like a dictionary).

Can we use map as array in C++? ›

C++ allows us a facility to create an array of maps. An array of maps is an array in which each element is a map on its own.

What are the 7 different types of maps? ›

List of different types of Maps
  • Physical Maps.
  • Topographic Maps.
  • Political Maps.
  • Weather Maps.
  • Economic Maps.
  • Resource Maps.
  • Population Maps.
  • World Maps.
6 Oct 2021

What are the 3 basic attributes of maps? ›

Some common features of maps include scale, symbols, and grids. All maps are scale models of reality. A map's scale indicates the relationship between the distances on the map and the actual distances on Earth. This relationship can be expressed by a graphic scale, a verbal scale, or a representative fraction.

What are 3 things maps are used for? ›

Maps represent the real world on a much smaller scale. They help you travel from one location to another. They help you organize information. They help you figure out where you are and how to get where you want to go.

What is map and explain its types? ›

There are two main types of maps - political maps and physical maps. Physical maps show the shape of the land - hills, lakes, forests, the coast and so on. Political maps show how the land is used by people - counties, provinces, countries, town boundaries, etc.

What are the 6 types of map? ›

Some of the most common types are political, physical, topographic, climate, economic, and thematic maps.

What are the 7 types of data? ›

And there you have the 7 Data Types.
  • Useless.
  • Nominal.
  • Binary.
  • Ordinal.
  • Count.
  • Time.
  • Interval.
29 Aug 2018

What are the methods of mapping? ›

6 Main Methods to Create Process Maps
  • Through individual staff or small group interviews.
  • Through facilitated discovery workshops.
  • Through analysis of existing documentation.
  • Through direct work observation.
  • Through business analysis design.
  • Through import/use of existing process documentation.
19 Feb 2021

Why is data mapping used? ›

Data mapping is the process of connecting a data field from one source to a data field in another source. This reduces the potential for errors, helps standardize your data, and makes it easier to understand your data by correlating it, for example, with identities.

Where is data mapping used? ›

Data mapping is essential for any company that processes data. It's mainly used to integrate data, build data warehouses, transform data, or migrate data from one place to another. The process of matching data to a schema is a fundamental part of the flow of data through any organization.

What is meaning of the mapping? ›

/ˈmæp.ɪŋ/ the activity or process of making a map: the mapping of underground sites.

What are the 5 types of maps? ›

The 5 Different Types of Maps
  • General Reference Map. General reference maps show important physical areas. ...
  • Topographical Map. Topographical maps share quite a few characteristics with general maps. ...
  • Thematic Map. ...
  • Navigational Charts. ...
  • Cadastral Maps and Plans.
19 Oct 2021

What is a mapping table? ›

Definition. A mapping table is a business data table of correspondence for mapping an input set of values to a set of output values according to different periods of time.

How do you do mapping? ›

How to create a process map
  1. Step 1: Identify a problem or process to map. ...
  2. Step 2: List the activities involved. ...
  3. Step 3: Write out the sequence of steps. ...
  4. Step 4: Draw a flowchart using process mapping symbols. ...
  5. Step 5: Finalize and share the process map. ...
  6. Step 6: Analyze the map to find areas of improvement. ...
  7. Flowchart.
24 May 2022

How many elements can a map store C++? ›

In C++, map::max_size returns the max. number of elements. In a vanilla map , there's an upper bound of at most SIZE_T_MAX elements, which is 2^64-1 on modern hardware.

Can maps have duplicate values C++? ›

C++ Software Engineering

Multi-map in C++ is an associative container like map. It internally store elements in key value pair. But unlike map which store only unique keys, multimap can have duplicate keys.

Is map and HashMap same C++? ›

The Map is an interface, and HashMap is a class of the Java collection framework. The Map interface can be implemented by using its implementing classes. In comparison, the HashMap class implements the Map interface. The Map contains unique key-pair values.

What are mapping values? ›

“Mapping Values” is a British Academy-funded pilot project that will run for 12 months (until April 2022). It combines participatory map-making, digital humanities, oral history, and walking workshops.

Can I search by value in map C++? ›

Search by value in a Map in C++

Given a set of N pairs as a (key, value) pairs in a map and an integer K, the task is to find all the keys mapped to the give value K. If there is no key value mapped to K then print “-1”. Explanation: The 3 key value that is mapped to value 3 are 1, 2, 10.

What is the default value of map in C++? ›

By default, In Primitive datatypes such as int, char, bool, float in C/C++ are undefined if variables are not initialized, But a Map is initially empty when it is declared.

Can map store multiple values? ›

A standard Java HashMap cannot store multiple values per key, any new entry you add will overwrite the previous one.

What is multi value map? ›

A MultiValueMap decorates another map, allowing it to have more than one value for a key. A MultiMap is a Map with slightly different semantics. Putting a value into the map will add the value to a Collection at that key. Getting a value will return a Collection, holding all the values put to that key.

Can HashMap contain multiple values? ›

In these cases, we can use Collections such as list, set, etc. to insert multiple values into the same key in HashMap.

Is vector a list C++? ›

List in C++ stores the elements at the non-contiguous memory location. It is considered a doubly linked list internally. A vector in C++ stores the elements at the contiguous memory location. It is considered to be a type of dynamic array internally.

How many libraries are in C++? ›

The C++ Standard Library includes the 1990 C Standard Library and, hence, includes these 18 headers.
...
Standard C++ Library Header Files.
Standard C++ HeaderCorresponding Standard C & C++ Header
<ciso646><iso646.h>
<climits><limits.h>
<clocale><locale.h>
<cmath><math.h>
14 more rows

Are C++ arrays on stack or heap? ›

Unlike Java, C++ arrays can be allocated on the stack. Java arrays are a special type of object, hence they can only be dynamically allocated via "new" and therefore allocated on the heap.

What is set and map in C++? ›

The difference is set is used to store only keys while map is used to store key value pairs. For example consider in the problem of printing sorted distinct elements, we use set as there is value needed for a key. While if we change the problem to print frequencies of distinct sorted elements, we use map.

Is a map a binary tree C++? ›

C++ maps are internally represented as binary search trees.

What is the difference between map () and filter ()? ›

Map: returns an array of pieces of information from the original array. In the callback function, return the data you wish to be part of the new array. Filter: returns a subset of the original array based on custom criteria.

How do I convert a map value to an array? ›

Use keys() method on Map Object to get the keys of Map. Then use the array. from() method to convert map object to array.

What is difference between mapping and array? ›

Maps are special objects per se, they are iterables with key value pair constructor that looks like a 2D array but acts like an object. They offer a better flexibility in terms of choosing our key values. A map can have a key value which can be a string, number, object or even NaN.

Which is better map or array? ›

Map is iterable

While an Array , as brought up in the question, is also iterable, a Map offers a better use-case for key-value mappings than an Object would. Being iterable has a number of benefits, just-in-time execution and guaranteed order being two examples.

What are the 7 types of maps? ›

Some of the different types of maps are:
  • Physical Maps.
  • Topographic Maps.
  • Political Maps.
  • Weather Maps.
  • Economic Maps.
  • Resource Maps.
  • Population Maps.
  • World Maps.
6 Oct 2021

How many types of data mapping are there? ›

Within data mapping, there are three main techniques that are used — manual mapping, semi-automated mapping, and automated mapping.

What are the 3 types of maps Class 6? ›

NCERT Book Solutions Class 6 Chapter 4

In this chapter, students will get to learn about three types of maps: Physical Maps, Political Maps and Thematic Maps.

What are the 5 uses of maps? ›

Answer: Generally, we use maps as a reference to show political boundaries, landforms, water bodies, and the positions of cities. Maps also help us to know the routes of an area, landmarks, location (latitudes and longitudes) of a building or things, etc.

What are the 7 basic elements of a map? ›

Map Elements. Most maps contain the same common elements: main body, legend, title, scale and orientation indicators, inset map, and source notes. Not all are necessary or appropriate for every map, but all appear frequently enough that they're worth covering.

What are the types of mapping methods? ›

Different types of mapping techniques
  • Choropleth maps. Choropleth maps show interval data (data that is linked, rather than data from different categories) as colours. ...
  • Isoline maps. Isoline maps show lines that join up areas or values that are equal. ...
  • Dot maps. ...
  • Proportional symbols.

Which 3 Ways data map can be used? ›

Data mapping is the key to data management
  • Data migration. Data migration is the process of moving data from one system to another as a one-time event. ...
  • Data integration. Data integration is an ongoing process of regularly moving data from one system to another. ...
  • Data transformation.

What is a map 4 class? ›

A map is a drawing of the whole or part of the Earth's surface. 3. A physical map shows rivers, mountains and plateaus. 4. The components of map are also known as the language of a map.

What is a map Class 3 answer? ›

A map is a representation or drawing of the earth's surface or a part of its area drawn on a flat surface. A map is always made according to a scale. There are different types of maps like political, physical and thematic.

Top Articles
Latest Posts
Article information

Author: Amb. Frankie Simonis

Last Updated:

Views: 6272

Rating: 4.6 / 5 (76 voted)

Reviews: 91% of readers found this page helpful

Author information

Name: Amb. Frankie Simonis

Birthday: 1998-02-19

Address: 64841 Delmar Isle, North Wiley, OR 74073

Phone: +17844167847676

Job: Forward IT Agent

Hobby: LARPing, Kitesurfing, Sewing, Digital arts, Sand art, Gardening, Dance

Introduction: My name is Amb. Frankie Simonis, I am a hilarious, enchanting, energetic, cooperative, innocent, cute, joyous person who loves writing and wants to share my knowledge and understanding with you.