gpt4 book ai didi

c++ - 为什么我无法检索变体的索引并使用它来获取其内容?

转载 作者:行者123 更新时间:2023-12-02 20:46:01 24 4
gpt4 key购买 nike

我正在尝试访问变体的内容。我不知道里面有什么,但幸运的是,该变体知道。所以我想我只需询问变体它所在的索引,然后使用该索引来 std::get 其内容。

但这不能编译:

#include <variant>

int main()
{
std::variant<int, float, char> var { 42.0F };

const std::size_t idx = var.index();

auto res = std::get<idx>(var);

return 0;
}

错误发生在std::get调用中:

error: no matching function for call to ‘get<idx>(std::variant<int, float, char>&)’
auto res = std::get<idx>(var);
^
In file included from /usr/include/c++/8/variant:37,
from main.cpp:1:
/usr/include/c++/8/utility:216:5: note: candidate: ‘template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(std::pair<_Tp1, _Tp2>&)’
get(std::pair<_Tp1, _Tp2>& __in) noexcept
^~~
/usr/include/c++/8/utility:216:5: note: template argument deduction/substitution failed:
main.cpp:9:31: error: the value of ‘idx’ is not usable in a constant expression
auto res = std::get<idx>(var);
^
main.cpp:7:15: note: ‘std::size_t idx’ is not const
std::size_t idx = var.index();
^~~

我该如何解决这个问题?

最佳答案

编译器需要知道 idx 的值在编译时 std::get<idx>()工作,因为它被用作模板参数。

第一个选项:如果代码要在编译时运行,则将所有内容设置为 constexpr :

constexpr std::variant<int, float, char> var { 42.0f };

constexpr std::size_t idx = var.index();

constexpr auto res = std::get<idx>(var);

这有效是因为 std::variantconstexpr友好(其构造函数和方法都是 constexpr )。

第二个选项:如果代码不打算在编译时运行(很可能是这种情况),则编译器无法在编译时推断 res 的类型,因为它可能是三个不同的东西( intfloatchar )。 C++是静态类型语言,编译器必须能够推导出 auto res = ... 的类型来自后面的表达式(即它必须始终是相同的类型)。

您可以使用std::get<T> ,使用类型而不是索引,如果您已经知道它将是什么:

std::variant<int, float, char> var { 42.0f }; // chooses float

auto res = std::get<float>(var);

一般情况下,使用std::holds_alternative检查变体是否持有每种给定类型,并分别处理它们:

std::variant<int, float, char> var { 42.0f };

if (std::holds_alternative<int>(var)) {
auto int_res = std::get<int>(var); // int&
// ...
} else if (std::holds_alternative<float>(var)) {
auto float_res = std::get<float>(var); // float&
// ...
} else {
auto char_res = std::get<char>(var); // char&
// ...
}

或者您可以使用std::visit 。这稍微复杂一些:您可以使用与类型无关并且适用于所有变体类型的 lambda/模板函数,或者传递带有重载调用运算符的仿函数:

std::variant<int, float, char> var { 42.0f };

std::size_t idx = var.index();

std::visit([](auto&& val) {
// use val, which may be int&, float& or char&
}, var);

参见std::visit了解详细信息和示例。

关于c++ - 为什么我无法检索变体的索引并使用它来获取其内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59103484/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com