2

I'm working on a tuple class for C++03. I want to be able to construct it from a list, which is tricky since the tuple's length can vary.

#ifndef N_TUPLE_H
#define N_TUPLE_H


template <typename T, int N>
class N_Tuple
{
 public:
  N_Tuple(T values[N]);
 private:
  T values_[N];
};


template <typename T, int N>
N_Tuple< T, N >::N_Tuple(T values[N])
{
  for (int i = 0; i != N; ++i)
    values_[i] = values[i];
}


#endif

Currently, I have to do this:

int arr[] = { 0, 1, 2 };
N_Tuple< int, 3 > t(arr);

It seems clunky and not very user-friendly. Is it possible to reduce this to a single line in C++03?

Thanks in advance.

Patrick
  • 455
  • 4
  • 11
  • According to the answer in http://stackoverflow.com/questions/13267277/where-can-we-use-list-initialization "In C++03 you can only use list-initialization for aggregates (C++03 [dcl.init.aggr]) and scalar (C++03 [dcl.init]/13) types" Which means you can't do it for arrays. – Jerry Jeremiah Jun 22 '15 at 03:45
  • @JerryJeremiah *"Which means you can't do it for arrays."* Huh? Arrays *are* aggregates. – dyp Jun 22 '15 at 07:50
  • I must have read that wrong the n... Sorry about that. – Jerry Jeremiah Jun 22 '15 at 07:55
  • @Patrick Your tuple looks very unlike a `std::tuple` but much more like a `std::array` class. The boost.assign library contains `list_of`, which can be used to initialize a `boost::array` like this: `boost::array arr = list_of(0)(1)(2);` -- [live demo](http://coliru.stacked-crooked.com/a/d76a51babe172d13) – dyp Jun 22 '15 at 07:56
  • gcc extension for compound literal? – user3528438 Jun 22 '15 at 10:11
  • Please, if you have an answer to your own question, then post it as an *answer*, not as an edit to your question. – dyp Jun 22 '15 at 13:04
  • Umm.. well great that you've removed the answer from your question, but now that information is gone (invisible) for anyone finding your question. Why don't you add it as an answer to your own question? It is allowed and encouraged to answer your own question.. – dyp Jun 23 '15 at 20:00

2 Answers2

1

It seems clunky and not very user-friendly. Is it possible to reduce this to a single line in C++03?

Since you are basically imitating std::array, just rid of the constructor:

template <typename T, int N>
class N_Tuple
{
 public:
  T values_[N];
};

Note, in this, you have to make the values_ public.

That way you can initialize them just as you expect:

N_Tuple<int,3> p = {1,2,3};

This is valid in both C++03 and C++11, no extensions of any kind (Tr1, Boost or whatever) required.

Another alternative is to hide the helper array behind a macro. The basic idea is to initialize your helper array and from there your tuple-esque array. But since you'd want the array's contents to come after in the initializing notation (var x = contents) you'd have to use something like a prolog-epilog macro which will require some repetition and you'll have to be careful with the comma in your particular type's case:

SOME_MACRO_BEGIN(My_Sequence_type, t) = {1, 2, 3} 
SOME_MACRO_END(My_Sequence_type, t);

I've worked on such a solution that is compatible with both C++03 and C++11 (provided you do implement an initializer_list constructor for the C++11 case) without any particular requirements on the C++03 side of things.

(I am not sure how would it ever be possible to do it in a single macro, since a list of elements would contain commas which are processed specially for the macro and variadic macros are not a thing in C++03)

But unless your list is short or you abbreviate the names for the prolog-epilog macros a lot, it won't likely fit in a single line.

(Moreover, it still requires copying of the data, even though for the most simple kinds of types that won't ever matter)

Luis Machuca
  • 1,047
  • 9
  • 16
0

If you have access to Boost, you can use Assignment Library

There even is info on how to use it right here on SO.

Community
  • 1
  • 1
MatiasFG
  • 576
  • 2
  • 8