Как создать список кортежей C ++ - PullRequest
8 голосов
/ 26 июня 2011

Я довольно новичок в C ++, у меня нет никакого опыта в этом.Я пытаюсь создать список кортежей, первым будет int, вторым будет строка.

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

И получаю ошибку.Я хочу иметь возможность создать список, добавить записи, которые я могу отсортировать по int, и получить строку, описывающую, что это было за int.

Как бы я создал этот список?

Ответы [ 4 ]

12 голосов
/ 26 июня 2011

Для простого списка используйте 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 на самом деле является реализациейдвусвязный список, который вам может не понадобиться.

9 голосов
/ 03 августа 2016

Ответы здесь немного устарели и не говорят вам, как отсортировать список.

Поскольку C ++ 11 , вы можете использовать стандарт tuple, например vector:

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

Для добавления записей вы можете использовать метод emplace_back из vector. Вот пример чтения из стандартного ввода:

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

Для сортировки достаточно использовать стандартную функцию sort, поскольку int является первым элементом кортежа в нашем случае, порядок сортировки по умолчанию будет сортировать элементы по int s сначала, затем string s:

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

Вы можете получить значения из кортежа по индексу:

get<0>(data[i])

или по типу:

get<int>(data[i])

Я собрал полный пример, который вы можете увидеть вживую на ideone .

1 голос
/ 26 июня 2011

Может быть неуместно, но если «часть создания» содержит заполнение списка элементами, 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");
}

В зависимости от вашего сценария курса.

0 голосов
/ 26 июня 2011

Так же, как примечание:

Новый стандарт 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;

Это должно работать почти на всех последних компиляторах.

...