Адресация кортежей в C ++ 14 по типам — разве это не просто неверное предположение?

C ++ 14 Википедия описывает новую языковую особенность адресация кортежей по типу, с помощью которого вы могли бы написать:

tuple<string, string, int> t("foo", "bar", 7);
int i = get<int>(t);        // i == 7

Ну, как правило, это не получается, т. Е. В общем случае кортеж имеет более одного элемента одного типа. Это довольно специфический (хотя и общепризнанный) вид кортежей, которые имеют одно значение для каждого типа; и этот вид получает вид подразумевает семантику get<T>(t) быть своего рода T-представление t, как будто значения в разных типах так или иначе связаны между собой.

Почему хорошая идея иметь такой метод, который не применяется в общем случае и, кажется, имеет отношение к некоторым, ну, я думаю, вы могли бы сказать, подклассы кортежей?

1

Решение

Я думаю, что основной мотивацией является то, что решение std::tuple по позиции не очень читабелен или не очень устойчив; от обоснование:

Предположим, у нас есть функция get_employee_info, которая возвращает некоторую информацию о сотрудниках в кортеже. Сказать что-то вроде получить<2> (get_employee_info (…) на самом деле не говорит о том, что мы ищем офис сотрудника. Более того, если позже мы будем заинтересованы в возвращении другого атрибута сотрудника, нам может понадобиться настроить индексы по всей программе.

Конечно, это может быть сделано только для уникальных типов. Однако можно использовать, например, классы enum, легкие обертки для таких вещей, как std::stringи т.д., чтобы их было легче читать и поддерживать.

Вот быстрый пример:

#include <tuple>
#include <string>
#include <iostream>

struct FirstName : std::string { using std::string::basic_string; };
struct LastName : std::string { using std::string::basic_string; };

struct EmployeeID
{
EmployeeID(int id) : employeeID_m(id) { }
operator int() const { return employeeID_m; }
const EmployeeID &operator=(int id) { employeeID_m = id; return *this; }
int employeeID_m;
};

using Record = std::tuple<FirstName, LastName, EmployeeID>;

void printRecord(const Record &r)
{
std::cout << std::get<FirstName>(r) << " "<< std::get<LastName>(r)
<< "'s employee ID is "<< std::get<EmployeeID>(r)
<< std::endl;
}

int main() {

Record record1 = std::make_tuple(FirstName("Slim"), LastName("Jim"), EmployeeID(12233));
Record record2 = std::make_tuple(FirstName("Big"), LastName("Bill"), EmployeeID(33221));

printRecord(record1);
printRecord(record2);

return 0;
}

С выходом:

Slim Jim's employee ID is 12233
Big Bill's employee ID is 33221
4

Другие решения


По вопросам рекламы [email protected]