c++unordered-mapostreamstdany

Cant cout item in container with std::any


This script

#include <iostream>
#include <unordered_map>
#include <any>
using namespace std;

int main() {
    unordered_map<int, any> test;
    test[5] = "Hey!";
    cout << test[5];
    return 0;
}

Why does it not work?

candidate function not viable: no known conversion from 'std::__ndk1::unordered_map<int, std::__ndk1::any, std::__ndk1::hash<int>, std::__ndk1::equal_to<int>, std::__ndk1::allocator<std::__ndk1::pair<const int, std::__ndk1::any> > >::mapped_type' (aka 'std::__ndk1::any') to 'const void *' for 1st argument; take the address of the argument with &
    basic_ostream& operator<<(const void* __p);

Sorry if this sounds a little stupid


Solution

  • Just add a any_cast to test[5]. The main reason for this cast, is to tell the compiler which overloaded function of << is to be called for test[5], << doesn't have any function defined for std::any. Hence, we told the compiler to call const char * or std::string overload function of <<.

    Always, make sure that sizeof of allocation of test[n] must match the sizeof type-cast. For an example:

    sizeof(std::string) = 32 bytes

    sizeof(const char *) = 8 bytes

    That's why we first need to allocate test[5] using std::string("Hey!");, instead of just "Hey!".

    But, sizeof(int *) is equal to sizeof(char *), if you did this, it can cause 3 problems:

    1. segfault
    2. undefined behavior
    3. Exception: std::bad_any_cast

    Fix

    std::cout << std::any_cast<const char *>(test[5]);
    

    or std::string

    test[5] = std::string("Hey!");
    std::cout << std::any_cast<std::string>(test[5]);