'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 1:[1]
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:
- segfault
- undefined behavior
- 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]);
Solution 2:[2]
This is because there is no defined overload for the <<
operator for a std::ostream
and std::any
.
<<
is defined for string literals, std::string
s, numbers, and a few other specific objects. std::any
is none of those.
Just because it happens to actually contain a string doesn't make it into a std::string
or anything else. Just because you open the door to your car, go inside and sit down, or put your dog into the car, or a bunch of groceries, doesn't turn your car into a human, or dog, or a bunch of vegetables. It's still a car, just with something inside it.
So there is no <<
operator defined for this. That's what your C++ compiler is telling you: it needs the <<
operator defined for std::ostream
and std::any
and there isn't one.
Solution 3:[3]
To solve the error you can use std::any_cast
which gives type-safe access to the contained object, as shown below:
std::cout << std::any_cast<const char*>(test[5]);
Or
test[5] = std::string("Hey!");
std::cout << std::any_cast<std::string>(test[5]);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Sam Varshavchik |
Solution 3 | Darth-CodeX |