用法c ++ 11 std :: tuple在大项目中

时间:2014-02-15 16:05:11

标签: c++ c++11 tuples stdtuple

C ++ 11添加了非常有用的容器std :: tuple,现在我可以将许多结构转换为std :: tuple:

// my Field class
struct Field 
{
     std::string path;
     std::string name;
     int id;
     int parent_id;
     int remote_id;    
};

//create
Field field = {"C:/", "file.txt", 23, 20, 41 };  

 //usage
  foo( field.path );
  field.name= new_name;
  int id = field.id;

//to std::tuple,               /--path,  /--name      /--id, /--parend_id,   /--remote_id
using Field = std::tuple< std::string, std::string , int,   int ,           int >;

//create
auto field = make_tuple<Field>("C:\", "file.txt", 23, 20, 41);      



// usage
     foo( std::get<0>(field) );  // may easy forget that the 0-index is path
     std::get<1>(field) = new_name; // and  1-index is name
     int id = std::get<2>(field);   // and 2-index is id, also if I replace it to 3, 
                       //I give `parent_id` instead of `id`, but compiler nothing say about.

但是,在大型项目中使用std :: tuple只有一个缺点 - 可能很容易忘记每种类型元组的含义,因为这里不能通过名称访问,只能通过索引访问。

因此,我会使用旧的Field类。

我的问题是,我可以简单而美丽地解决这个缺点吗?

4 个答案:

答案 0 :(得分:5)

是的,你可以简单而美妙地解决这个缺点:

使用正确的工具来完成工作!在这种情况下,结构或类。

在这种情况下,元组并不意味着替换结构。只是因为你的工具箱里有一把新的闪亮的锤子并不意味着你现在应该用它来砍伐木头。

答案 1 :(得分:4)

嗯,概念上tuple和普通的struct非常相似。主要区别在于使用名称访问struct的成员,而使用索引访问tuple的成员。

所以你似乎想用tuple作为结构 - 为什么不只使用struct

答案 2 :(得分:1)

您可以使用枚举来提供“字段名称”:

enum FIELDS { path, name, id, parent_id, remote_id };
auto field = make_tuple<Field>("C:\", "file.txt", 23, 20, 41);      

foo( std::get<FIELDS::path>(field) );  // may easy forget that the 0-index is path
std::get<FIELDS::name>(field) = new_name; // and  1-index is name
int id = std::get<FIELDS::id>(field);  

(编辑之后,我在这里使用的是枚举的合格版本,因为它们是相当常见的字段名称,但并不是绝对必要的)

答案 3 :(得分:1)

一般情况下,您应该只将tuple用于将在彼此的几行内包装和使用的数据,或者当您实际上不知道数据是什么而不是您需要打包的数据时它在一起。有时两者都有。

这使得它对于通用编程非常有用,例如,打包一些参数并在以后解压缩它们。或者,如果你有一个本地lambda,你希望得到一个子结果,并且不想为它创建一个结构 - 但即使这样,我也会被一个结构诱惑。

tuple的一个很好的用途是让您的struct通过std::tie方法返回其参数的tuplemake_tie个参考号)(和const版本)。 tuple为您编写类似词汇operator<的内容,在某些情况下会导致<==甚至=的防错实施(默认情况下)等式不是很正确,但你想调用默认的相等作为子问题。)