【问题标题】:How to create a list of tuples C++如何创建元组列表 C++
【发布时间】:2011-06-26 05:37:32
【问题描述】:

我是 C++ 的新手,我真的没有任何背景。我想创建一个元组列表,第一个是 int,第二个是字符串。

  #include <string>
  #include <list>
  #include <boost/tuple/tuple.hpp>
  ....
  list< tuple<int,string> > time;

并得到一个错误。我希望能够创建一个列表,添加可以按 int 排序的条目,并拥有描述 int 是什么的字符串。

我将如何创建此列表?

【问题讨论】:

  • 愚蠢的问题:你记得添加 using namespace std / using namespace boost 吗?您收到的具体错误消息是什么?
  • 你有没有“使用命名空间提升;”在你的代码中?我猜你需要一个“使用命名空间标准;”也是。
  • 我认为,你可以使用 std::map 来达到这个目的。它将保存对 int-string,自动按 int 值排序。 Here 是描述。
  • 你是对的,我错过了使用命名空间提升。哈哈,习惯了,谢谢!

标签: c++ list boost tuples


【解决方案1】:

对于简单的列表,请使用 std::vector 而不是 std::list

您可能只想要一些简单的东西,例如:

#include <iostream>
#include <vector>
#include <string>
#include "boost/tuple/tuple.hpp"

using namespace std;
using boost::tuple;

typedef vector< tuple<int,string> > tuple_list;

int main(int arg, char* argv[]) {
    tuple_list tl;
    tl.push_back( tuple<int, string>(21,"Jim") );

    for (tuple_list::const_iterator i = tl.begin(); i != tl.end(); ++i) {
        cout << "Age: " << i->get<0>() << endl;
        cout << "Name: " << i->get<1>() << endl;
    }
}

std::list 实际上是一个你可能不需要的双向链表的实现。

【讨论】:

  • 在这种情况下,有没有一种简单的方法可以按年龄对其进行排序?我必须编写自己的排序函数吗?
【解决方案2】:

这里的答案有点过时了,并没有告诉你如何对列表进行排序。

由于C++11,您可以使用标准tuple,例如vector

#include <tuple>
#include <vector>
// ...
vector<tuple<int, string>> data;

要添加条目,您可以使用vectoremplace_back 方法。 这是从标准输入读取的示例:

#include <iostream>
// ...
int age;
string name;
while(cin >> age >> name) data.emplace_back(age, name);

要排序,使用标准的sort函数就足够了,因为在我们的例子中int是元组的第一个元素,默认排序顺序会先按ints对元素进行排序,然后按strings:

#include <algorithm>
// ...
sort(data.begin(), data.end());

您可以通过索引retrieve values from a tuple

get<0>(data[i])

或按类型:

get<int>(data[i])

我整理了一个full example that you can see live at ideone

【讨论】:

    【解决方案3】:

    这里可能不相关,但如果“创建部分”包含用元素填充列表,Boost.Assign 可能会很有用。你可以这样做:

    #include <boost/assign/list_of.hpp>
    #include <vector>
    
    int main()
    {
        typedef boost::tuple<int, std::string> tuple;
    
        std::vector<tuple> v = boost::assign::tuple_list_of(1, "foo")(2, "bar");
    }
    

    当然取决于你的场景。

    【讨论】:

      【解决方案4】:

      顺便说一句:

      新的 C++ 标准引入了可变参数模板以及元组。 gcc 和 Visual Studio(至少)支持这些。因此,如果您有可能(即,如果所有支持的编译器都支持已经很有可能的元组),您可以使用它。

      唯一的问题是,一些编译器在 std::tr1 命名空间中仍然有元组,而其他编译器已经在 std 命名空间中有它。有时您还需要包括有时 .但是您可以配置您的构建系统来定义一些宏来帮助您支持多种方案。例如,如果您只需要支持 Visual Studio 10 和/或全新的 gcc 版本,您可以执行以下操作:

      #include <list>
      #include <string>
      #include <tuple>
      
      std::list<std::tuple<int, string> > time;
      

      例如,您可以使用 cmake 生成一个头文件,该文件为您带来对所有支持元组的编译器的支持(并且工作量稍大,甚至可以使用 boost 作为后备)。

      为此,您需要创建一个类似于 tuple.h.cmake 的文件:

      #if defined( __GNUC__ ) && (__GNUC__ * 100 + __GNUC_MINOR__ < 430)
      # define GCC_OLDER_THAN_430 1
      #endif
      
      #if defined( _MSC_VER ) && (_MSC_VER < 1600 /* 2010 */)
      # define MSC_OLDER_THAN_2010 1
      #endif
      
      #if defined( GCC_OLDER_THAN_430 )
      # define TR1_IN_TR1_SUBDIRECTORY 1
      #endif
      
      #if defined( ZORBA_GCC_OLDER_THAN_430 ) || defined( ZORBA_MSC_OLDER_THAN_2010 )
      # define TR1_NS_IS_STD_TR1 1
      #endif
      
      #ifdef TR1_NS_IS_STD_TR1
      # define TR1_NS std::tr1
      #else
      # define TR1_NS std
      #endif
      
      #ifdef TR1_IN_TR1_SUBDIRECTORY
      #  include <tr1/tuple>
      #else
      #  include <tuple>
      #endif
      

      那么,上面的例子将如下所示:

      #include <string>
      #include <list>
      #include "tuple.h"
      
      std::list<TR1_NS::tuple<int, std::string> > time;
      

      这应该适用于几乎所有最新的编译器。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-05-10
        • 2021-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多