我有下面的代码,为什么 visitor1
和 visitor2
给出错误?
这是否意味着访问者不能返回变体中的一种类型?
#include <iostream>
#include <variant>
struct Visitor1
{
template <class T>
T operator()(const T & t) const
{
return (t);
}
};
struct Visitor2
{
int operator()(const int & t) const
{
return std::get<int>(t);
}
char operator()(const char & t) const
{
return std::get<char>(t);
}
};
struct Visitor3
{
void operator()(const int & t) const
{
std::cout<<t;
}
void operator()(const char & t) const
{
std::cout<<t;
}
};
int main()
{
std::variant<int, char> v{char(100)};
std::visit(Visitor3{}, v);
auto t = std::visit(Visitor2{}, v); //fails
//auto t = std::visit(Visitor1{}, v); //fails
std::cout << t;
}
我知道我可以使用 std::get()
,但问题是我只能使用 auto
与 std::get()
,如果我做类似下面的事情,x
在 if/else 范围之外无法访问:
bool b;
Variant v;
if (b)
{
auto x = std::get<int>(v);
}
else
{
auto x = std::get<char>(v);
}
// I want to do something with x here out of if/else
最佳答案
可以存在一种具有 C++ 的许多功能的语言,它可以满足您的需求。
为了执行您想要的操作,当您调用 std::visit
时,必须编写该函数其余部分的 N 个不同实现。
在这 N 个不同的实现中的每一个(在您的例子中是 2 个),变量的类型都会不同。
C++ 不是这样工作的。
与访问调用“相乘”的代码的唯一部分是访问者。
int main()
{
std::variant<int, char> v{char(100)};
std::visit([&](auto && t){
std::cout << t;
}, v);
}
我将 函数体的其余部分 放在访问者中。该代码针对可存储在访问者中的每种类型实例化一次。
从访问中返回的任何内容都会返回到调用范围的“单个实例”主体。
基本上,[&](auto&& t)
lambda 执行您似乎想要的操作。
现在,我们可以做一些小技巧来稍微改变一下语法。
我最喜欢的是:
v->*visit*[&](auto&& val) {
std::cout << val;
return [val](auto&& x) { x << val; };
}->*visit*[&](auto&& outputter) {
outputer(std::cout);
};
->*visit*
使用相对荒谬的元编程来允许
引起访问的命名运算符,
将访问的返回值融合到变体中。
但没有正常人会写出这样的代码。
关于c++ - 如何使用访问者从变体返回特定类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53159681/