[英]How can I print map key/value with std::variant?
I'm trying to print the key of a certain value in my dictionary.我正在尝试在我的字典中打印某个值的键。 I defined my map like this:我这样定义了我的 map:
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?有人可以帮我解决这个错误吗?
There's no operator<<
for std::variant
, which can't be printed out directly. std::variant
没有operator<<
,不能直接打印出来。 You need to read the value from the variant (by index or type), eg您需要从变体中读取值(按索引或类型),例如
std::cout << std::get<bool>(kwargs["flag"]) << std::endl;
Or或者
std::cout << std::get<2>(kwargs["flag"]) << std::endl;
You can define operator<<
for your type:您可以为您的类型定义operator<<
:
std::ostream& operator<<(std::ostream& os, std::variant<float,int,bool,std::string> const& v) {
std::visit([&os](auto const& x) { os << x; }, v);
return os;
}
You can generalize the solution to work with any variant
specialization:您可以推广解决方案以使用任何variant
专业化:
template <class Var, class = std::variant_alternative_t<0, Var>>
std::ostream& operator<<(std::ostream& os, Var const& v) {
std::visit([&os](auto const& x) { os << x; }, v);
return os;
}
Note, the second template parameter exists to disable the definition if the Var
is not a std::variant
specialization.注意,如果Var
不是std::variant
特化,则存在第二个模板参数以禁用定义。
I would use std::visit
with a generic lambda that prints any type to std::cout
, as follows:我会将std::visit
与通用 lambda 一起使用,它将任何类型打印到std::cout
,如下所示:
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 <<
.这是因为所有的float
、 int
、 bool
和std::string
都有 output stream 运算符<<
的重载。 For other types, or to override this behaviour, you could use a custom functor class instead of a lambda:对于其他类型,或覆盖此行为,您可以使用自定义函子 class 而不是 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";
注意:不幸的是,行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 ).实际上 select 不是变体类型的std::string
构造函数,因为字符串文字优先转换为bool
而不是std::string
( 进一步阅读)。 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
.您可以通过使用例如std::string{"probe"}
或标准std::string
用户定义文字显式创建std::string
来避免这种情况,如"probe"s
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.