如何使用std :: variant打印地图键/值?

时间:2020-07-03 01:51:37

标签: c++ dictionary variant

我正在尝试在字典中打印某个值的键。我这样定义地图:

std::map<std::string, std::variant<float,int,bool,std::string>> kwargs; 
kwargs["interface"] = "probe"; 
kwargs["flag"] = true; 
kwargs["Height"] = 5; 
kwargs["length"] = 6; 

我试图正常打印该值,但是出现(没有运算符“ <<”与这些操作数匹配)错误。

std::cout << kwargs["flag"] << std::endl; 

有人可以帮助我解决这个错误吗?

3 个答案:

答案 0 :(得分:3)

operator<<没有std::variant,不能直接打印出来。您需要从变体中读取值(按索引或类型),例如

std::cout << std::get<bool>(kwargs["flag"]) << std::endl; 

std::cout << std::get<2>(kwargs["flag"]) << std::endl; 

答案 1 :(得分:3)

您可以为您的类型定义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;
}

您可以概括该解决方案以与任何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;
}

请注意,如果Var不是std::variant专门化,则存在第二个模板参数以禁用定义。

答案 2 :(得分:2)

我将std::visit与通用lambda一起使用,该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';
}

之所以可行,是因为floatintboolstd::string中的所有输出流运算符<<都有重载。对于其他类型,或者要覆盖此行为,可以使用自定义仿函数类而不是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);

注意:很不幸,行kwargs["interface"] = "probe";实际上没有为变量类型选择std::string构造函数,因为字符串字面量优先转换为{{1} },而不是boolfurther reading)。您可以通过使用std::string或标准std::string用户定义的文字(例如std::string{"probe"})显式制作一个std::string来避免这种情况。

Live demo