Skip to content

reference member #1809

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
BjarneStroustrup opened this issue Jul 18, 2021 · 8 comments
Open

reference member #1809

BjarneStroustrup opened this issue Jul 18, 2021 · 8 comments

Comments

@BjarneStroustrup
Copy link
Contributor

I think we need a rule banning reference members. All we have is a note: (Note that using a reference member is almost always wrong.)

@shaneasd
Copy link
Contributor

Related/Duplicate: #1707

@hsutter
Copy link
Contributor

hsutter commented Jul 22, 2021

We have this in C.12 so perhaps a PR to propose updates to that?

@Ivarun
Copy link

Ivarun commented Nov 15, 2024

I’m curious why this is desirable? Aren’t reference members (passed as constructor parameters) a perfectly valid way to do dependency injection in C++?

@eyalroz
Copy link

eyalroz commented Apr 27, 2025

(I'm ignoring the note - which is not a guideline; see #1707 about that one)

While references as members can make a class somewhat unwieldy - non-assignable, non-movable - I can't say I understand why @BjarneStroustrup believes such members should be banned. I'm not even convinced they should be discouraged. When one wants a reference-type member, the three main options seem to be:

The appeal of a reference relative to the other two, is that it hides - when used - its referential nature: You use it as you would a value-type. It is often convenient or appealing to me as a class designer that my users don't have to say mystruct.foo but *(mystruct.bar). Also, it is non-nullable, unlike a pointer, which would require the extra hassle of non_null.

Personally, I would avoid references in a class I design as part of, say, the public API of a library. But for something internal which doesn't have to be super robust and has limited scope - I wouldn't strongly oppose their use.

@GuillaumeDua
Copy link

From my perspective, a guideline should discourage the use of reference members, as it makes lifetime management harder and may lead to dangling reference;
But when needed (like, for DI for instance), then std::reference_wrapper seems the best option to meet std::semiregular requirements.

@eyalroz
Copy link

eyalroz commented Apr 27, 2025

@GuillaumeDua : Well, discourage is not as drastic than "almost always wrong"...

But let me push back a little...

  • std::reference_wrapper is not default-constructible, so - not semi-regular.
  • How do std::reference_wrapper or pointers reduce the chance of having a dangling reference? I'd say they would be just as likely to dangle.

@jwakely
Copy link
Contributor

jwakely commented Apr 28, 2025

std::reference_wrapper is for passing references through APIs that would otherwise decay them, such as std::bind and std::thread. It's not supposed to be a general purpose semiregular reference type.

@GuillaumeDua
Copy link

@eyalroz @jwakely Silly/tired me, you're right. I meant from a copyable and movable perspective.
std::reference_wrapper does not reduce changes of dangling ref.
My point was "avoid to use ref as members, but if you really want/need to, then use ref-wrapper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants