3

I want to make a templated class for labeled/named tuples as in each type of the tuple is associated with a static std::string.

When creating a new labeled tuple, I want to invoke it in the following way:

auto a = std::labeled_tuple<"key1", int, "key2", double>()

The number of strings has to match the number of types provided and obviously the length is variadic.

Syntactically the following is incorrect but it should further clarify what I want:

template<typename...template<std::string STR, typename Arg> T>

And I want to access STR... and T...

Any help would be appreciated, thanks.

ggobieski
  • 149
  • 1
  • 14
  • 1
    Well to begin with you should not put it in the `std` namespace, that's not allowed. – Some programmer dude Feb 15 '19 at 14:32
  • 1
    You can't use `std::string` as a template parameter since it needs to allocate (disregarding SSO) – NathanOliver Feb 15 '19 at 14:33
  • 1
    I'm also very interested in *why* you need such a data-structure? What is the *real* problem that is supposed to solve? Please read about [the XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) as this questions seems to be one. – Some programmer dude Feb 15 '19 at 14:36
  • @Someprogrammerdude I know at least one usage of this - self-described structures (read - serialization). Until we have compile-time introspection, it is going to be a sore point. – SergeyA Feb 15 '19 at 14:42
  • OP: are you trying to implement home-grown compile time introspection? – SergeyA Feb 15 '19 at 14:43
  • There is no good way to use strings as template parameters, even if you ignore the variadic/paired requirements: https://stackoverflow.com/questions/2033110/passing-a-string-literal-as-a-parameter-to-a-c-template-class. Your only other path is `constexpr` functions taking the strings. – Max Langhof Feb 15 '19 at 14:46
  • Okay so I put a char * there instead of std::string. Also this not for compile time introspection, it's actually just some additional information for the tuple (mainly for printing). I could probably pass this information later on, but I know this information at compile time so I figured it would be neat if you could do it with templates. – ggobieski Feb 15 '19 at 15:02

1 Answers1

1

Instead create "labeled" types:

template <const char* Name, typename T>
struct labeled_type
{
     static constexpr const char* name = Name;
     T value;
};

Then use regular std::tuple:

static constexpr const char key1[] = "key1";
static constexpr const char key2[] = "key2";

auto a = std::tuple<labeled_type<key1, int>, labeled_type<key2, double>>();

Demo

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • Might be as close as I can come to what I actually want. I would access the value using std::get<0>(a).value, which is a little unfortunate, but overall not bad. – ggobieski Feb 15 '19 at 16:41
  • `operator T&` might still be added for convenience. – Jarod42 Feb 15 '19 at 16:43
  • @Jarod42: Does this code work? I tried with gcc (https://rextester.com/CMTT36894) and clang (https://rextester.com/UIWVZD63898) and both compilers give errors. – Constantinos Glynos Feb 15 '19 at 17:53
  • @ConstantinosGlynos: Having pointer in template is tricky, array cannot go anywhere [working demo](https://rextester.com/VDCYZ42225) – Jarod42 Feb 15 '19 at 18:00
  • @Jarod42: Damn memory addresses. I forgot the "rule" with `static constexpr`! My bad... – Constantinos Glynos Feb 15 '19 at 18:14