I need a trivially copyable tuple-like class, but no suitable implementations exist, I could not come up with one myself and I think one might even not be possible. The reason for it are references. A ::std::tuple
can hold references, but a trivially copyable tuple might not be able to, since it may not have non-trivial constructors and references would have to be initialized in the constructors of the tuple-like class and storing a reference wrapper would make the tuple-like class non-trivial. My questions are in the title.

- 69,038
- 19
- 164
- 304

- 14,119
- 9
- 58
- 116
-
My question does not refer to ::std::tuple at all, but to a custom tuple, it is not a duplicate. I actually think such a tuple might be possible. – user1095108 Aug 30 '16 at 14:02
-
Do you need reference support? Would [this implementation](http://stackoverflow.com/questions/38393302/returning-variadic-aggregates-struct-and-syntax-for-c17-variadic-template-c/38394375#38394375) help? – Revolver_Ocelot Aug 30 '16 at 14:23
-
@Revolver_Ocelot yes, after some fixing. https://github.com/user1095108/generic/blob/master/many.hpp maybe there are still bugs. – user1095108 Aug 30 '16 at 19:31
2 Answers
It's not clear what you are referring to when you discuss references.
Yes, if a particular tuple stored reference types, then it wouldn't be trivially copyable. But that's true for any type. If a type is not trivially copyable, then a type which contains that type as a subobject will also not be trivially copyable.
You cannot write a tuple which imposes trivial copyability on types that are not themselves trivially copyable.
But otherwise, it is entirely possible to write a tuple type which will be trivially copyable if all of the component types are themselves trivially copyable. That's the best guarantee you're going to get. And if you want to ensure that users never give non-trivially copyable types, you can always add a static_assert
that all of the types in the typelist are trivially copyable.

- 1
- 1

- 449,505
- 63
- 781
- 982
-
A tuple containing references (logically) need not store references (physically). For example, it could contain pointers, and expose references. – Yakk - Adam Nevraumont Aug 30 '16 at 15:42
-
Storing references using reference_wrapper
is entirely possible:
std::reference_wrapper
is guaranteed to be TriviallyCopyable. (since C++17)
Just having a non-trivial non-special constructor (as e.g. std::reference_wrapper<T>::reference_wrapper(T&)
) is absolutely fine. So the same holds for your trivially_copyable_tuple
; as long as it has a trivial copy constructor, trivially_copyable_tuple::trivially_copyable_tuple(int&, float&, char)
is fine.
And actually, you don't need to use std::reference_wrapper
at all; while a reference type is not TriviallyCopyable, a class type containing a reference is itself TriviallyCopyable (although it is not Pod, StandardLayoutType, DefaultConstructible, TriviallyDefaultConstructible, or Trivial).
Here's a few examples:
- my own tuple implementation, showing that no special tricks are needed to make it TriviallyCopyable;
- a very slightly more involved implementation showing that if you provide reseating assignability (so need to use a
reference_wrapper
-alike internally) you can still preserve all the other properties; - a tuple with through assignability showing that you lose trivial copyability, but only on tuples actually containing a reference type; you can retain trivial copyability on tuples containing scalars.

- 152,476
- 27
- 293
- 366
-
"*while a reference type is not TriviallyCopyable, a class type containing a reference is itself TriviallyCopyable*" This is only true if that class makes itself trivially copyable somehow. And I'm not sure how it could do that without deleting the copy/move constructors. – Nicol Bolas Aug 30 '16 at 17:56
-
3@NicolBolas where does the Standard say that a class type containing a reference is not trivially copyable? I can't find it in [class.copy]/11-12. Edit: you aren't thinking of copy assignment, are you? – ecatmur Aug 30 '16 at 18:31
-
It does require deleting the copy assignment, though, which makes it slightly less useful. (Of course, the alternative is reseating; you can't assign through the reference without making the assignment operator non-trivial.) – T.C. Aug 30 '16 at 19:15
-
@T.C. yes, fair enough. Added reference wrapping/unwrapping by storing a reseatable pointer. – ecatmur Aug 30 '16 at 19:38
-
2One complication: `tuple
` and `tuple – Howard Hinnant Aug 31 '16 at 00:44>` have different copy assignment semantics. The former assigns through the reference. The latter resets the reference to refer to the rhs. -
@HowardHinnant thanks, I'd got a bit confused and forgotten what `tuple
` actually does. So the properties depend on the desired semantics, but you can always retain the desirable properties if you just store scalars. – ecatmur Aug 31 '16 at 09:57