C++ 使用std::get访问std::variant<;指数>;
如何使用C++ 使用std::get访问std::variant<;指数>;,c++,std,c++17,variant,C++,Std,C++17,Variant,如何使用v.index()然后std::get(v)访问变量的成员 当变量具有多个相同类型的条目时非常有用 以下方法不起作用。这段代码既不能在GCC上编译,也不能在clang上编译 #include <iostream> #include <variant> #include <string> #include <sstream> typedef std::variant<int, int, std::string> foo; st
v.index()
然后std::get(v)
访问变量的成员
当变量具有多个相同类型的条目时非常有用
以下方法不起作用。这段代码既不能在GCC上编译,也不能在clang上编译
#include <iostream>
#include <variant>
#include <string>
#include <sstream>
typedef std::variant<int, int, std::string> foo;
std::string bar(const foo f) {
const std::size_t fi = f.index();
auto ff = std::get<fi>(f);
std::ostringstream ss;
ss << "Index:" << fi << " Value: " << ff;
return ss.str();
}
int main()
{
foo f( 0 );
std::cout << bar(f);
}
更新为询问如何解决,而不是错误消息的含义。还包括解释:
只有当f
也被声明为constepr
时,代码get(f)
才能工作;但是,只有当变量中的所有类型都有平凡的析构函数时,这才是可能的,而std::string
没有析构函数。std::get
在请求编译时已知的变量索引时适用
如果您需要对一个变量值执行操作,而该变量值的类型直到运行时才知道,惯用的方法是使用带有std::visit
的访问者
#include <iostream>
#include <variant>
#include <string>
struct output_visitor
{
template< typename T >
void operator() ( const T& value ) const
{
std::cout << value;
}
};
int main()
{
std::variant<int, std::string> f( 0 );
std::visit( output_visitor{}, f );
}
#包括
#包括
#包括
结构输出访问者
{
模板
void运算符()(常量T和值)常量
{
std::coutstd::get
的模板参数必须是变量中元素的索引或类型。因此,您可以选择
、
、
或
。实际上,标准指定了std::size_t@md5i非类型模板参数可以是与参数不同的类型,只要存在可用的唯一隐式转换(粗略地说)实际上是关于如何输出变体的当前活动成员的问题(不一定使用get
)@M.M是的,我想是的。特别是当变量中有一个类型的多次使用时。谢谢!我更新了一个更好的问题。我如何解决这个问题,而不是错误消息的意思。还有一个更复杂的例子。@KarlM你就是不能做get
,类型必须在编译时知道。我不理解你的评论。当然,类型在编译时是已知的。@KarlM编译std::string bar(const foo f)时不知道
f
的活动成员是int
还是string
;因此不能有一个表达式引用f
的活动成员,因为在编译时不知道该表达式的类型,所以constepr.我理解。那么我该怎么办?注意:OP特别询问了变量类型列表中的重复类型;在这种情况下,您不能使用初始值设定项(0)
,还有更多关于“谢谢”的示例!另外,我想知道index()的值-不用于直接访问。我想你可以通过output_visitor构造函数传入f。这就是答案?你如何区分这个visitor中的第一个int
和第二个呢?@Slava如果这个区别很重要(不是仅仅为了输出值),那么你也可以阅读f.index()
在任何阶段
candidate template ignored: invalid explicitly-specified argument for template parameter '_Tp'
<source>:10:29: error: the value of 'fi' is not usable in a constant expression
auto ff = std::get<fi>(f);
^
<source>:9:23: note: 'fi' was not initialized with a constant expression
const std::size_t fi = f.index();
constexpr std::size_t fi = f.index();
#include <iostream>
#include <variant>
#include <string>
struct output_visitor
{
template< typename T >
void operator() ( const T& value ) const
{
std::cout << value;
}
};
int main()
{
std::variant<int, std::string> f( 0 );
std::visit( output_visitor{}, f );
}
#include <iostream>
#include <variant>
#include <string>
int main()
{
std::variant<int, std::string> f( 0 );
std::visit( [](auto v){std::cout << v;} , f );
}