Dereferencing a temporary pointer to initialize a reference member variable

Viewed 158

I am working with an external library which can hold large data structures. Calls to it return pointers to objects which it manages:

class ExternalLib {
public:
  int* GetLargeObject() { return &large_object; };

private:
  int large_object = 1;
};

I am trying to write a wrapper for this external library which can hold a const reference to the large data structure I am interested in:

class ExternalLibraryWrapper {
public:
  ExternalLibraryWrapper() : large_object_ref(*ext.GetLargeObject()){};

private:
  ExternalLib ext;
  const uint &large_object_ref;
};

However, I get the compiler warning:

Reference member 'large_object_ref' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object [clang: dangling_member]

From my understanding, ext.GetLargeObject() returns a temporary pointer to the address of (*this).ext.large_object. Shouldn't the compiler know that the constructed object &large_object_ref isn't actually binding to a temporary object?

1 Answers

A temporary is materialized when binding a reference when the initializer is a prvalue or when type of the initializer differs from the type of the reference by more than cv-qualifiers but can be converted to it (unless of course that conversion is user-defined and yields a reference). (This case is rejected in the case of an lvalue reference to non-const; the const U& case is accepted for historical reasons. It would have been nicer to have const T&& from the beginning and have it mean “you may pass temporaries, and I won’t modify whatever you pass”, but that’s not where we are.)

Obviously dereferencing a pointer produces an lvalue, so this warning (very useful since it’s impossible to use the reference so initialized!) indicates that the type mismatch pertains in your case.

Related