AnswerBun.com

How can I have a C++ set with more than 1 data type?

Stack Overflow Asked by blakcy88 on December 18, 2020

Trying to learn C++ coming from Python, and in python a set can have multiple types. How do I do this in C++? I’m specifically trying to have a set with both integers and strings. For example:

#include <set>
#include <string>
using namespace std;

int main() {
    set<int, string> s;
    s.insert(1);
    s.insert("string");
    
}

One Answer

Having multiple types of elements in a container is called a heterogenous container.

C++ supports this from C++17 using std::any which can hold any type, or as EOF said using std::variant when you want to define the set of possible types yourself.

Here is a demo of std::any using std::any_cast:

#include <any>
#include <iostream>
#include <list>
#include <map>
#include <set>

int main()
{
    std::list<std::any> any_list;

    int myInt = 1;
    std::string myString("I'm a string");

    using MapType = std::map<std::list<int>, std::string>;
    MapType myMap;

    struct CustomType {
        void* pointer;
    };

    any_list.emplace_back(std::any());
    any_list.emplace_back(myInt);
    any_list.emplace_back(myString);
    any_list.emplace_back(myMap);
    any_list.emplace_back(CustomType());

    // To show the awesome power of std::any we add
    // the list as an element of itself:
    any_list.emplace_back(any_list);

    for(auto& element: any_list) {
        if(!element.has_value()) {
            std::cout << "Element does not hold a value" << std::endl;
            continue;
        }

        if (int* someInt = std::any_cast<int>(&element)) {
            std::cout << "Element is int: " << *someInt << 'n';
        } else if (std::string* s = std::any_cast<std::string>(&element)) {
            std::cout << "Element is a std::string: " << *s << 'n';
        } else if (std::any_cast<MapType>(&element)) {
            std::cout << "Element is of type MapTypen";
        } else if (std::any_cast<CustomType>(&element)) {
            std::cout << "Element is of type CustomTypen";
        } else {
            std::cout << "Element is of unknown but very powerful typen";
        }
    }
}

This yields output:

Element does not hold a value
Element is int: 1
Element is a std::string: I'm a string
Element is of type MapType
Element is of type CustomType
Element is of unknown but very powerful type

The pre-C++17 method of doing this is obviously a struct with manual type info and void*.

Note that I used std::list instead of std::set because std::any does not have operator< defined by default. This could be solved by defining your own comparison predicate.

My personal opinion is that usually when you think you want to use a heterogenous container it's worth re-evaluating your design and stick to normal homogenous containers, but it's there if you need it :-)

Answered by VexingParse on December 18, 2020

Add your own answers!

Related Questions

How to toggle button text when clicked with JavaScript in HTML

6  Asked on December 21, 2020 by marcosvaldez81

     

Why is getDate() a month off?

3  Asked on December 21, 2020 by aztheog

   

Using GLOB to match each character in an SQLite TEXT field

2  Asked on December 21, 2020 by anagramdatagram

   

Timeout on a function call

18  Asked on December 21, 2020 by teifion

       

How can I access a variable inside a nested array?

2  Asked on December 21, 2020 by intelltanito

   

OkHttpClient doesn’t add headers to requests

2  Asked on December 21, 2020 by ghaylen

         

Can someone teach me how to get this output

2  Asked on December 20, 2020 by surtz

 

Match multiple exact routes

3  Asked on December 20, 2020 by magofoco

   

Return a 0 if no rows are found in Microsoft SQL Server

2  Asked on December 20, 2020 by henk-hadders

     

What’s the good way to pass data to a thread in c++?

4  Asked on December 20, 2020 by ting-wang

   

Firestore query single document

2  Asked on December 20, 2020 by zvi-karp

     

Expand nested arrays postgres

1  Asked on December 20, 2020 by dan-wolchonok

         

grpc python measure response time

1  Asked on December 20, 2020 by user3599803

     

gtkmm load from resource plain text file

1  Asked on December 19, 2020 by tophyd-ayur

   

Ask a Question

Get help from others!

© 2022 AnswerBun.com. All rights reserved. Sites we Love: PCI Database, MenuIva, UKBizDB, Menu Kuliner, Sharing RPP