玩耍的同时std::variant
and std::visit
出现了以下问题:
考虑以下代码:
using Variant = std::variant<int, float, double>;
auto lambda = [](auto&& variant) {
std::visit(
[](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, int>) {
std::cout << "int\n";
} else if (std::is_same_v<T, float>) {
std::cout << "float\n";
} else {
std::cout << "double\n";
}
},
variant);
};
它工作得很好,如以下示例所示:
lambda(Variant(4.5)); // double
lambda(Variant(4.f)); // float
lambda(Variant(4)); // int
那么为什么以下会失败:
using Variant = std::variant<int, float, double>;
auto lambda = [](auto&& variant) {
std::visit([](auto&& arg) { return arg; }, variant);
};
auto t = lambda(Variant(4.5));
由于静态断言
static_assert failed due to requirement '__all<is_same_v<int
(*)(__value_visitor<(lambda at main.cc:25:7)> &&,
__base<std::__1::__variant_detail::_Trait::_TriviallyAvailable, int, float,
double> &), float (*)(__value_visitor<(lambda at main.cc:25:7)> &&,
__base<std::__1::__variant_detail::_Trait::_TriviallyAvailable, int, float,
double> &)>, is_same_v<int (*)(__value_visitor<(lambda at main.cc:25:7)> &&,
__base<std::__1::__variant_detail::_Trait::_TriviallyAvailable, int, float,
double> &), double (*)(__value_visitor<(lambda at main.cc:25:7)> &&,
__base<std::__1::__variant_detail::_Trait::_TriviallyAvailable, int, float,
double> &)> >::value' "`std::visit` requires the visitor to have a single
return type."
std::visit
显然可以推导出类型arg
正如成功的例子所示。那么为什么要求有单一返回类型呢?
编译器是Apple LLVM version 10.0.1 (clang-1001.0.46.4)
but gcc version 8.3.0
失败并出现类似错误。