将 std::any 转换为 std::tuple

Casting std::any to std::tuple

提问人:ilarcangelo 提问时间:11/6/2023 最后编辑:HolyBlackCatilarcangelo 更新时间:11/6/2023 访问量:54

问:

我有这段代码......

class TableModel {
 public:
  TableModel(std::vector<std::string> header = {},
                 std::string tableName = "")
      : header_(header.begin(), header.end()),
        tableName_(tableName) {}

  std::vector<std::string> header() { return header_; }

  size_t columns() { return header_.size(); }

  size_t rows() { return rows_.size(); }
  
  template <typename... Args>
  auto cell(const size_t row, const size_t col){
      if(row < 0 or row > rows()){
          throw std::out_of_range("Invalid row index value");
      }
      auto t = rows_[row]; // first issue

      /*Here it returns a std::any but it should be a std::tuple data type*/
      /*once cast done, it should return the value in the col position. but*/
      
      return get<col>(t); //second issue
      /*it is not working due get function is quite special*/
  }

  /*This works as a charm*/
  template <typename... Args>
  void addRow(Args &&...args) {
    rows_.emplace_back(std::tuple(std::forward<Args>(args)...));
  }

 private:
  std::vector<std::string> header_;
  std::string tableName_;
  std::vector<std::any> rows_; // root of problems
};

我想做这件事很有趣,而不是做一个数组或向量的向量(或相关)。 我不知道您是否可以帮助我从std::any转换为std::tuple,一旦完成,根据所需的位置获取元组中的数据。

我尝试使用可变参数将行声明为字符串的元组,但不起作用std::vector<std::tuple<std::string...>> rows_;

非常感谢

C++ C++17 标准图盒 stdany

评论


答:

2赞 Keyboard Corporation 11/6/2023 #1

std::tuple并非旨在以您尝试使用可变参数模板的方式使用它们。

在代码中,是无效的,因为需要固定数量的类型参数,而不是可变数量的参数。这就是为什么您在尝试声明时遇到错误的原因std::tuple<std::string...>std::tuplestd::vector<std::tuple<std::string...>> rows_;

如果要存储字符串元组,可以声明将替换的位置替换为要存储的字符串数。但是,这不是很灵活,因为您需要在编译时知道字符串的数量。std::tuple<std::string, std::string, ...> rows_;...

更好的方法可能是使用 of 将字符串存储在每一行中。这允许您在每行中存储可变数量的字符串。std::vector<std::string>

我将您的类修改为这种方法;TableModel

class TableModel {
 public:
 TableModel(std::vector<std::string> header = {},
                std::string tableName = "")
     : header_(header.begin(), header.end()),
       tableName_(tableName) {}

 std::vector<std::string> header() { return header_; }

 size_t columns() { return header_.size(); }

 size_t rows() { return rows_.size(); }
 
 std::string cell(const size_t row, const size_t col){
     if(row < 0 or row > rows()){
         throw std::out_of_range("Invalid row index value");
     }
     return rows_[row][col];
 }

 template <typename... Args>
 void addRow(Args &&...args) {
   rows_.emplace_back(std::vector<std::string>{std::forward<Args>(args)...});
 }

 private:
 std::vector<std::string> header_;
 std::string tableName_;
 std::vector<std::vector<std::string>> rows_;
};

在上面的代码中,字符串向量的向量。每个内部向量表示表中的一行,内部向量中的每个字符串表示行中的一行。cell 函数返回指定单元格中的字符串。该函数将新行添加到表中。rows_ iscelladdRow

此方法比使用方法更灵活,因为它允许您在每行中存储可变数量的字符串。但是,它确实需要您管理向量的向量,这可能比使用单个向量更复杂。std::tuple