C/C++:std::get

模板函数std::get()是一个辅助函数,它能够获取到容器的第n 个元素。模板参数的实参必须是一个在编译时可以确定的常量表达式,编译时会对它检查。

#include <variant>
#include <string>
 
int main()
{
    std::variant<int, float> v{12}, w;
    int i = std::get<int>(v);
    w = std::get<int>(v);
    w = std::get<0>(v); // 效果同前一行
 
//  std::get<double>(v); // 错误: [int, float] 中无 double
//  std::get<3>(v);      // 错误:合法的 index 值是 0 和 1
 
    try {
      std::get<float>(w); // w 含有 int ,非 float :将抛出异常
    }
    catch (std::bad_variant_access&) {}
}

#include <iostream>
#include <string>
#include <tuple>
 
int main()
{
    auto t = std::make_tuple(1, "Foo", 3.14);
 
    // Index-based access
    std::cout << "( " << std::get<0>(t)
              << ", " << std::get<1>(t)
              << ", " << std::get<2>(t)
              << " )\n";
 
    // Type-based access (C++14 or later)
    std::cout << "( " << std::get<int>(t)
              << ", " << std::get<const char*>(t)
              << ", " << std::get<double>(t)
              << " )\n";
 
    // Note: std::tie and structured binding may also be used to decompose a tuple.
}
这个错误信息来源于C++代码中对`std::tuple`构造时出现的问题,具体来说是在尝试初始化`std::tuple`成员变量的过程中出现问题。以下是详细的解释以及解决方法: --- ### 错误原因分析 从错误提示来看: ``` clude/c++/11/tuple:1819:9: error: array used as initializer 1819 | : first(std::forward<_Args1>(std::.get<_Indexes1>(__tuple1))...) ``` 这表明你在构建`std::tuple`实例的时候,可能试图用一个数组作为初始值传递给它的一个元素。然而,C++不允许直接将数组作为另一个类型的初始化表达式(例如传递到构造函数),除非明确将其转换为目标类型。 #### 示例问题代码 假设我们有这样的代码片段: ```cpp #include <tuple> #include <utility> int main() { int arr[3] = {1, 2, 3}; std::tuple<int, double[]> t(42, arr); // ❌ 编译失败 } ``` 这里的`double[]`是一个非法的数组声明形式,而即便换成合法的形式,比如`std::array<double, N>`,也需要正确的适配才能成功初始化元组内的元素。 --- ### 解决方案 为了修复这个问题,我们需要避免直接使用裸数组或未明确定义的对象参与初始化。以下是几种常见做法: #### 方法一:使用 `std::initializer_list` 如果目标是简单的数值集合,可以用`std::initializer_list`代替原始数组: ```cpp #include <tuple> #include <vector> int main() { auto initList = {1, 2, 3}; // 初始化列表 std::tuple<std::vector<int>> t(initList); } ``` #### 方法二:显式包装成容器(如 `std::array` 或 `std::vector`) 如果你确实需要用到固定大小的数组,那么建议切换至`std::array`这样的标准库工具箱类型: ```cpp #include <tuple> #include <array> int main() { std::array<int, 3> arr = {1, 2, 3}; std::tuple<std::array<int, 3>> t(arr); // 正确 } ``` #### 方法三:编写自定义辅助函数帮助转换 当面临复杂情况时,可以通过编写专门的帮助函数来进行适当的类型转换工作: ```cpp template<typename T, size_t N> auto to_tuple(T (&arr)[N]) { return std::make_tuple(std::begin(arr), std::end(arr)); } int main() { int rawArray[5] = {0, 1, 2, 3, 4}; auto tupleFromArr = to_tuple(rawArray); // 现在可以正常操作生成好的 tuple ... } ``` --- ### 结论 上述三种方式都能有效规避“array used as initializer”的编译期报错现象,选择哪一种取决于实际需求及上下文环境的要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值