2015-04-18 1 views
1

C++14 Wikipedia page описывает новую функцию языковой tuple addressing by type, с которым вы могли бы сделать запись:C++ 14 кортежей для адресации по типу - разве это не делает вообще недействительное предположение?

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

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

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

+3

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

ответ

4

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

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

конечно, это может быть сделано только для уникальных типов. Тем не менее, можно было бы использовать, например, перечисления классов, легкие обертки для таких вещей, как 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 
+2

Я действительно не вижу, как обращение к нему по типу является более надежным. И если вам нужна ясность - вы все равно будете использовать структуру с именованными полями. Я на самом деле не покупаю его в качестве причины. – einpoklum

+1

Он поддерживает другой стиль программирования, вот и все. Например, если я добавляю поле «возраст» в качестве обернутого «int», мне не нужно модифицировать старый код для учета перестановки полей в 'tuple'. – sfjac

+0

Он поддерживает только этот «другой стиль», если это кортеж с уникальными типами. Или если вы сделаете их уникальными. Но если вы это сделали, хорошо ... просто используйте что-то другое, кроме кортежа. Что я могу сказать, я не уверен ... – einpoklum

 Смежные вопросы

  • Нет связанных вопросов^_^