I'm trying to print the key of a certain value in my dictionary. I defined my map like this:
std::map<std::string, std::variant<float,int,bool,std::string>> kwargs;
kwargs["interface"] = "probe";
kwargs["flag"] = true;
kwargs["Height"] = 5;
kwargs["length"] = 6;
I tried to print the value normally but a (no operator "<<" matches these operands) error occurs.
std::cout << kwargs["flag"] << std::endl;
Can someone help me with this error?
I would use std::visit
with a generic lambda that prints any type to std::cout
, as follows:
std::map<std::string, std::variant<float,int,bool,std::string>> kwargs;
kwargs["interface"] = "probe"s;
kwargs["flag"] = true;
kwargs["Height"] = 5;
kwargs["length"] = 6;
for (const auto& [k, v] : kwargs){
std::cout << k << " : ";
std::visit([](const auto& x){ std::cout << x; }, v);
std::cout << '\n';
}
This works because all of float
, int
, bool
, and std::string
have overloads for the output stream operator <<
. For other types, or to override this behaviour, you could use a custom functor class instead of a lambda:
struct PrintVisitor {
template<typename T>
void operator()(const T& t) const {
std::cout << t;
}
// prints std::string in quotes
void operator(const std::string& s) const {
std::cout << '\"' << s << '\"';
}
};
[...]
std::visit(PrintVisitor{}, kwargs);
NOTE: unfortunately, the line kwargs["interface"] = "probe";
doesn't actually select the std::string
constructor for the variant type, because the string literal preferentially converts to a bool
rather than a std::string
(further reading). You can avoid this by explicitly making a std::string
using, for example, std::string{"probe"}
or the standard std::string
user-defined literal, as in "probe"s
.