C ++ 14元组按类型寻址-难道它只是做出通常无效的假设?

ein*_*ica 1 c++ tuples rationale variadic-templates c++14

C ++ 14维基百科页面描述的新的语言功能,通过类型的寻址元组,与您可以做写:

tuple<string, string, int> t("foo", "bar", 7);
int i = get<int>(t);        // i == 7
Run Code Online (Sandbox Code Playgroud)

好吧,通常这会失败,即在通常情况下,一个元组具有多个相同类型的元素。这是一种非常特殊的(虽然我承认,这是很常见的)元组,但每个类型都有一个值。并且这种get隐含了-表示get<T>(t)形式的语义,好像不同类型中的值以某种方式相关。Tt

为什么拥有这样一种方法(在一般情况下不适用,并且似乎与某些情况相关)是一个好主意,我想您可以说出元组的子类吗?

sfj*_*jac 5

我认为主要的动机是std::tuple按职位来定位不是很容易理解,也不是很可靠。从原理上

假设我们有一个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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

Slim Jim's employee ID is 12233
Big Bill's employee ID is 33221
Run Code Online (Sandbox Code Playgroud)

  • 我真的看不到如何按类型寻址更可靠。而且,如果您想弄清楚-无论如何,您都应该使用带有命名字段的结构。我并不是真的将其购买作为理由。 (2认同)
  • 我觉得这很好。如果出于同样的原因而脆弱,请按数字顺序排序,因为您不想首先按数字对结构成员进行数字排序。元组优于结构的一个好处是,您可以*遍历元组,将其连接起来,等等,都可以使用模板元编程。同样,用于FirstName,LastName的习惯用法还是标准的。 (2认同)