通过字符串模板参数访问元组

Gaining access to the tuple by string template param

C++ 11 中的标准元组允许通过整数模板参数访问,如下所示:

tuple<int, double> test;
test.get<1>();

但是如果我想通过字符串模板参数访问:

test.get<"first">()

我该如何实施?

首先,std::tuple::get不是成员函数。有一个 non-member 函数 std::get.

给定,

std::tuple<int, double> test;

您无法使用以下方法获取第一个元素:

std::get<"first">(test);

您可以使用其他助记符:

const int First = 0;
const int Second = 1;
std::get<First>(test);
std::get<Second>(test);

如果这样可以使代码更易读。

R Sahu 提供了几个很好的助记符,不过我想添加另一个。您可以使用 C 风格枚举(即 non-class 枚举):

enum TupleColumns { FIRST, SECOND };

std::get<FIRST>(test);

如果像这样将枚举与智能枚举反射库结合使用:https://github.com/krabicezpapundeklu/smart_enum,那么您可以创建一组自动与字符串相互转换的枚举。因此您可以自动将列名转换为枚举并以这种方式访问​​您的元组。

所有这些都需要您在编译时提交您的列名和顺序。此外,您始终需要使用字符串文字或 constexpr 函数,以便您可以将枚举值作为 constexpr 以这种方式使用。

constexpr TupleColumns f(const char *);
constexpr auto e = f("first");
std::get<e>(test);

此时我可能应该添加一个警告:这是一个相当深的兔子洞,需要相当强大的 C++。我可能会从更大的角度寻找不同的解决方案,但我不太了解你的大局,我也不了解你的 C++ 水平和你的同事(假设你有他们)。

您可以创建自定义 constexpr 转换函数。我只是想证明 OP 想要的东西(几乎)是可能的。

#include <tuple>
#include <cstring>

constexpr size_t my_cast(const char * text)
{
    return !std::strcmp(text, "first") ? 1 :
           !std::strcmp(text, "second") ? 2 :
           !std::strcmp(text, "third") ? 3 :
           !std::strcmp(text, "fourth") ? 4 :
           5;
}

int main()
{
    std::tuple<int, double> test;
    std::get<my_cast("first")>(test);
    return 0;
}

这可以在 GCC 4.9.2 中用 C++11 (C++14) 编译。未在 Visual Studio 2015 年编译。