代码之家  ›  专栏  ›  技术社区  ›  Zifre

为什么C++中元组的使用不常见?

  •  116
  • Zifre  · 技术社区  · 17 年前

    为什么没有人在C++中使用元组呢? Boost Tuple Library

    元组允许你做各种很酷的事情,比如:

    tie(a,b) = make_tuple(b,a); //swap a and b
    

    这当然比这个好:

    temp=a;
    a=b;
    b=temp;
    

    swap(a,b);
    

    但是如果你想旋转三个值呢?可以使用元组执行此操作:

    tie(a,b,c) = make_tuple(b,c,a);
    

    元组有什么我没有想到的大缺点吗?如果没有,为什么很少使用?他们慢吗?或者只是人们不习惯他们?使用元组是个好主意吗?

    12 回复  |  直到 17 年前
        1
  •  125
  •   Trey Jackson    13 年前

    一个愤世嫉俗的答案是,许多人在C++中编程,但不理解和/或使用高级功能。有时这是因为他们是不被允许的,但许多人只是不尝试(甚至不理解)。

    作为一个非boost示例:有多少人使用中的功能 <algorithm> ?

    std::vector 和 std::list . 这就是为什么使用 boost::tuple 这并不常见。

        2
  •  43
  •   Alan De Smet    17 年前

    因为它还不是标准的。任何非标准的东西都有更高的障碍。Boost的一部分之所以流行,是因为程序员们都在叫嚣着要它们。(脑海中浮现出一幅哈什图)。但是,虽然tuple很方便,但它并不是一个压倒性的、明显的胜利,人们不会为此而烦恼。

        3
  •  23
  •   user21714    17 年前

    C++元组语法比大多数人更喜欢冗长的语法。

    考虑:

    typedef boost::tuple<MyClass1,MyClass2,MyClass3> MyTuple;
    

    因此,如果你想广泛使用元组,你要么到处都有元组typedef,要么到处都有令人烦恼的长类型名。我喜欢元组。我在必要时使用它们。但它通常仅限于两种情况,例如N元素索引或使用多重映射绑定范围迭代器对。它通常在一个非常有限的范围内。

    元组的有用性与声明、打包和解包所需的击键次数成反比。

        4
  •  10
  •   ojrac    17 年前

    对我来说,这是一种习惯:元组不能为我解决任何新的问题,只有一些我已经可以处理得很好的问题。交换价值观仍然比传统的方式更容易——更重要的是,我并没有真正考虑如何交换“更好”。这已经足够好了。

    struct s

        5
  •  8
  •   YeahStu    17 年前

    但是如果你想旋转三个值呢?

    swap(a,b);
    swap(b,c);  // I knew those permutation theory lectures would come in handy.
    

    好的,有了4个etc值,最终n元组的代码比n-1交换的代码要少。对于默认的交换,这会有6个赋值,而不是你自己实现一个三周期模板时的4个赋值,尽管我希望编译器能解决简单类型的赋值问题。

    tie(a,b,c) = make_tuple(b*c,a*c,a*b);
    

    打开包装有点尴尬。

    tie(a,b,c) = make_tuple(b,c,a);
    

    对于返回多个值,如果值的类型不兼容,则元组是完美的,但是如果调用者可能以错误的顺序获取它们,则有些人不喜欢元组。有些人根本不喜欢多个返回值,也不想通过简化它们来鼓励它们的使用。有些人只是喜欢用命名结构来表示输入和输出参数,可能无法用棒球棒说服他们使用元组。没有品味可言。

        6
  •  8
  •   igorlord    13 年前

    正如许多人指出的那样,元组并不像其他特性那样有用。

    1. 交换和旋转的噱头只是噱头。对于那些以前没有见过它们的人来说,它们是完全令人困惑的,而且因为几乎每个人都有,所以这些噱头只是糟糕的软件工程实践。

    2. 使用元组返回多个值比返回命名类型或使用命名引用更不需要自我记录。没有这种自文档化,很容易混淆返回值的顺序,如果它们是相互转换的,也不会更明智。

        7
  •  6
  •   Brian Neal    17 年前

    并不是每个人都能使用boost,而且TR1还没有被广泛使用。

        8
  •  5
  •   DanM    17 年前

    当在嵌入式系统上使用C++时,引入Boost库变得复杂。它们相互耦合,所以库的大小会增加。返回数据结构或使用参数传递而不是元组。在Python中返回元组时,数据结构是按照返回值的顺序和类型进行的,而不是显式的。

        9
  •  5
  •   Zack Yezek    13 年前

    因为一个元组真正代表的是一个匿名结构,所以在大多数情况下,大多数编码人员只使用真实的结构。

    如果“f”可能失败,您需要一个状态返回——毕竟,您不希望调用方必须检查每个参数来检测失败。“f”可能符合以下模式:

    struct ReturnInts ( int y,z; }
    bool f(int x, ReturnInts& vals);
    
    int x = 0;
    ReturnInts vals;
    if(!f(x, vals)) {
        ..report error..
        ..error handling/return...
    }
    

    std::tuple<int, int, bool> f(int x);
    int x = 0;
    std::tuple<int, int, bool> result = f(x); // or "auto result = f(x)"
    if(!result.get<2>()) {
        ... report error, error handling ...
    }
    

    另一个重要的缺点隐藏在这里——使用“ReturnInts”,我可以通过修改“ReturnInts”而不修改“f”的接口来添加alter“f”的return。如果tuple库提供的任何解决方案都不比tuple库差,那么tuple库提供的任何解决方案都不比tuple库差。

        10
  •  3
  •   Zac    17 年前

    当然,元组是有用的,但正如前面提到的,在真正使用元组之前,还需要一些开销和一两个障碍。

    一般来说,并不是每个人都已经安装了Boost,我当然不会为了它的元组功能而下载它并配置我的include目录来使用它。我想你会发现,已经使用Boost的人比不使用Boost用户更容易发现他们的程序中使用元组,而其他语言的移民(Python到大脑中)更容易对C++中缺少元组感到沮丧,而不是探索添加元组支持的方法。

        11
  •  1
  •   doron    9 年前

    作为数据存储 std::tuple 两者都有最坏的特点 struct 和一个数组;所有访问都是基于第n个位置的,但不能遍历 tuple 使用 for

    那么如果 如果在概念上是数组,我将使用数组,如果元素在概念上不是数组,则结构(具有命名元素)更易于维护。( a.lastname 这比 std::get<1>(a) ).

    这使得OP提到的转换成为元组唯一可行的用例。

        12
  •  0
  •   dirkgently    17 年前

    我有一种感觉,很多人使用Boost.Any和Boost.Variant(通过一些工程)而不是Boost.Tuple。