C++ Logo

std-proposals

Advanced search

Re: Container.iterator_to for getting an iterator form the reference to value

From: language.lawyer_at <language.lawyer_at_[hidden]>
Date: Thu, 13 Aug 2020 19:02:51 +0300
On 13/08/2020 18:56, Barry Revzin via Std-Proposals wrote:
> On Thu, Aug 13, 2020 at 9:58 AM Arthur O'Dwyer via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> To implement `iterator_to` for anything except `vector`, you have to rely
>> on a cast like this:
>>
>> struct Node {
>> T t;
>> Node *next;
>> };
>> Node *node_from_t(T *t) {
>> return reinterpret_cast<Node *>(t);
>> }
>> int main() {
>> Node n;
>> assert(node_from_t(&n.t) == &n);
>> }
>>
>> I'm not sure if this is well-defined. As long as `t` is the first member
>> of `Node`, I think it might actually be well-defined; but I wouldn't bet
>> money on it.
>> Problem is, library implementors tend to be *extremely* loath to rely on
>> anything smelling of UB in their implementations.
>>
>> my $.02,
>> –Arthur
>>
>
> This is well-defined. A pointer to the first non-static data member of a
> struct is pointer-convertible with a pointer to the struct

... if it is a standard-layout class.

A class S is a standard-layout class if it:
  - has no non-static data members of type non-standard-layout class

If T is not standard-layout class, pointers to a Node object and its first member subobject are not interconvertible.

But the code is still well-defined, you'll just have the same pointer value (pointer to the object of type T) after the reinterpret_cast<Node *>.

Received on 2020-08-13 11:06:17