【发布时间】:2019-07-08 18:00:52
【问题描述】:
我想在 std::variant 中获取活动值,但不知道哪个是活动的。我以为我可以编写一个模板访问者并使用 std::visit 但它不起作用。
#include <variant>
#include <string>
#include <iostream>
struct Visit_configuration {
template<typename Data_type>
Data_type operator()(Data_type& t) const
{
return t;
}
};
int main()
{
std::variant<int, std::string> v;
v = "hello";
std::cout << std::visit(Visit_configuration(), v); // expect "hello"
std::cin.get();
}
MSVC 不编译并抛出:
错误 C2338: visit() 需要所有潜在调用的结果 具有相同的类型和值类别(N4741 23.7.7 [variant.visit]/2)。
注意:参见函数模板实例化 'int std::visit&,0>(_Callable &&,std::variant &)' 正在编译
那么如何解决这个问题?
编辑:我想将获得的值也用于其他值,因此将 cout 放入模板中并不是我想要的。
【问题讨论】:
-
虽然您和我都可以看到
v将始终包含std::string,并且一个好的静态分析工具也可以做出该决定,但这超出了编译器所需的能力范围推断。值得注意的是,v不是constexpr,并且编译器在编译时不理解v包含的内容,而不是依赖于用户输入。所以无法确定std::visit的返回类型。 -
你应该让访问者
operator()输出值,而不是试图从访问者那里返回它以便调用者可以输出它。对于example:std::visit([](auto&& arg){std::cout << arg;}, v);