2

In the tutorial for the boost serialization library it says that "The serialization library detects when the object being serialized is an array" and therefore code like bus_stop * stops[10]; ar & stops; is equivalent to using a for loop for(i = 0; i < 10; ++i) { ar & stops[i]; }.

How can the library determine at runtime to how many elements the pointer stops points to? Or even that it actually is an array and not a pointer to a single object? I wasn't able to find any hint in the source code yet.

Thanks!

cwde
  • 214
  • 1
  • 10
  • See e.g. [this old question](http://stackoverflow.com/questions/437150/can-someone-explain-this-template-code-that-gives-me-the-size-of-an-array). – Some programmer dude Mar 06 '15 at 13:02
  • Variables in C++ have a statically known *type*, and you can write generic code that acts differently for different types. – Kerrek SB Mar 06 '15 at 13:04

1 Answers1

4

Notice that stops is not a pointer, it's an array (of 10 pointers to bus_stop, but that's irrelevant).

Arrays are not pointers. There is an implicit conversion from array to pointer to first element of the array which happens when you pass e.g. an array of char to a function expecting a char * parameter. But that conversion only happens when required.

If a function takes an array by reference, the conversion (also known as array-to-pointer decay) will of course not happen, so that the argument can bind to the parameter. In other words, all it takes is a suitable function template:

template <class T, std::size_t N>
void operator & (some_type lhs, T (&array)[N]);

This will only accept arrays as the right-hand side argument.

Notice that if, in your original code, you did this instead:

bus_stop * stops[10];
bus_stop ** p_stops = stops; // decay happens here

ar & p_stops;

then the last line would not invoke the array overload. The type of stops is an array. The type of p_stops is a pointer.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • 1
    Thanks for the good explanation. But what would the operator template for the pointer `p_stops` look like? If it would be a general implementation like `template void operator&(T* p)` then the operator `&` is ambigous for the array. – cwde Mar 06 '15 at 13:31
  • @cwde Yes, it would look like that, and no, it's not ambiguous. The array-based template matches perfectly. The pointer-based template would require an array-to-pointer conversion. Therefore, the array-based template is a strictly better match, and so is chosen. – Angew is no longer proud of SO Mar 06 '15 at 13:36
  • I just tried it in a simple code example with an array of 6 ints. The compiler (VS10) says the operator is ambiguous for it could be `operator &(T *)` or `operator &(T (&)[6])`. – cwde Mar 06 '15 at 13:57
  • @cwde Wow, you got me. I didn't expect that, but Clang reports the same ambiguity. I've never used Boost serialisation. Does it provide an overload for pointers? Perhaps that's just implemented as `void*`, not a template? That would disambiguate it. – Angew is no longer proud of SO Mar 06 '15 at 14:03
  • Yes with `void*` it is disambiguated, but that leads me to another question: how will the serialization process go on from there as one cannot dereference a `void*` pointer? Of course the answer must be somewhere in the source code of boost, but I can't figure out where to find it. Maybe someone else can help out here? – cwde Mar 06 '15 at 17:07
  • @cwde Does it actually need an overload for pointers at all? You can't meaningfully serialise a pointer anyway. At best, you could store the address it points to - but you can do that just fine with a `void*`. – Angew is no longer proud of SO Mar 06 '15 at 17:11
  • 1
    Hm at least it must have an overload ( see [this page](http://www.boost.org/doc/libs/1_52_0/libs/serialization/doc/tutorial.html#pointers) ). It will of course not store the address but the content it points to and therefore will call the operator for the dereferenced object. But this is not possible with a `void*`... Anyways I guess I should spend more time on going through the code so we don't get a lengthy comment discussion here :) – cwde Mar 06 '15 at 17:25