通过字符串模板参数获取对元组的访问权限

时间:2016-01-14 00:19:44

标签: c++ templates c++11 variadic-templates

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

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

但如果我想通过字符串模板param进行访问:

test.get<"first">()

我该如何实现呢?

3 个答案:

答案 0 :(得分:1)

您可以创建自定义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中编译。

答案 1 :(得分:0)

首先,std::tuple::get不是成员函数。有一个非成员函数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);

如果这使代码更易于阅读。

答案 2 :(得分:-1)

R Sahu提供了几个很好的助记符,但我想添加另一个。您可以使用C样式枚举(即非类枚举):

enum TupleColumns { FIRST, SECOND };

std::get<FIRST>(test);

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

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

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

我应该在这一点上添加一个警告:这是一个相当深的兔子洞,需要相当强大的C ++。我可能会在更大的图片中寻找一个不同的解决方案,但我不了解你的大局,也不知道你的C ++级别和你的同事(假设你有它们)。