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.

7
  • According to the answer in stackoverflow.com/questions/13267277/… "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. Commented Jun 22, 2015 at 3:45
  • @JerryJeremiah "Which means you can't do it for arrays." Huh? Arrays are aggregates. Commented Jun 22, 2015 at 7:50
  • I must have read that wrong the n... Sorry about that. Commented Jun 22, 2015 at 7: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<int, 3> arr = list_of(0)(1)(2); -- live demo Commented Jun 22, 2015 at 7:56
  • gcc extension for compound literal? Commented Jun 22, 2015 at 10:11

2 Answers 2

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)

Sign up to request clarification or add additional context in comments.

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.