Con*_*ngo 2 c++ c++11 c++17 pybind11
在 C++ 中,如何在运行时打印变体中包含的类型?
我的用例:使用pybind11将值字典从 Python 传递到 C++ ,我想打印出收到的类型。
Dan*_*ica 11
您可以获得带有std::visit一些类型名称打印库的通用解决方案,例如 Boost.TypeIndex。一个示例性的解决方案:
#include <iostream>
#include <type_traits>
#include <variant>
#include <boost/type_index.hpp>
int main()
{
std::variant<char, bool, int, double> v;
auto print_variant_type =
[](auto&& value)
{
using T = std::decay_t<decltype(value)>;
std::cout << boost::typeindex::type_id<T>().pretty_name() << std::endl;
};
v = 'a';
std::visit(print_variant_type, v); // prints out "char"
v = true;
std::visit(print_variant_type, v); // prints out "bool"
v = 1;
std::visit(print_variant_type, v); // prints out "int"
v = 1.0;
std::visit(print_variant_type, v); // prints out "double"
}
Run Code Online (Sandbox Code Playgroud)
现场演示: https: //godbolt.org/z/Web5zeGof
唯一的缺点是它可以打印作为类型别名的库类型的“丑陋”类型名称(例如std::string)。针对特定变体实例的替代方案(可能更适合您)可能是使用从变体索引到类型名称的映射:
using variant_type = std::variant<char, bool, int, double, std::string>;
static const std::array variant_type_names =
{ "char", "bool", "int", "double", "std::string" };
void print_variant_type(const variant_type& v)
{
assert(v.index() < variant_type_names.size());
std::cout << variant_type_names[v.index()] << std::endl;
}
int main()
{
variant_type v;
v = 'a';
print_variant_type(v); // prints out "char"
v = true;
print_variant_type(v); // prints out "bool"
v = 1;
print_variant_type(v); // prints out "int"
v = 1.0;
print_variant_type(v); // prints out "double"
v = std::string("some string");
print_variant_type(v); // prints out "std::string"
}
Run Code Online (Sandbox Code Playgroud)
现场演示: https: //godbolt.org/z/9na1qzEKs
您可以像这样使用函数重载:
#include <iostream>
#include <variant>
using VariantT = std::variant<int, float>;
namespace {
std::string name(const float& ) {
return "float";
}
std::string name(const int& ) {
return "int";
}
std::string variantName(const VariantT& v) {
return std::visit(
[](const auto &v) { return name(v); },
v
);
}
}
int main() {
std::variant<int, float> v;
v = 1;
std::cout << variantName(v) << std::endl;
v = 1.f;
std::cout << variantName(v) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)