2

I am designing a class that behaves like a C++ references but does some extra instrumental stuff (bookkeeping).

Initially I thought that std::reference_wrapper<T> would be a good model. But after a while I realized that std::reference_wrapper<T> doesn't behave, even in principle, as a C++ reference because assignment rebinds the internal pointer.

    double a = 5.;
    double b = 3.;
    double& ref = a;
    ref = b;
    assert(&ref != &b); // ref is not bound to b
    std::reference_wrapper<double> refwpr = a;
    refwpr = b;
    assert(&refwpr.get() == &b); // ref wrapper was rebound to b

I can of course change that behavior for my own class (not to rebind) but I though that maybe a class that emulates a reference is already out there. For example something like "std::real_reference<T>".

Is there a class (standard or not) that emulates references more closely?

I think it can be useful too, for example in many places one sees std::vector<std::reference_wrapper<T>> presented as an alternative to std::vector<T&> but this is misleading because the semantics is different but could be achieved with some modifications std::vector<std::real_reference<T>>.


I now think that if a "perfect" reference wrapper were possible, then references could be just implemented with pointers and we wouldn't need T& but just simply have a library feature reference<T> that works exactly like T& in all respects....

... which in turn means that the language could allow you to "overload" the & attribute over types to produce a custom type instead of a language reference. For example using mytype& = custom_reference_emulator_of_mytype.

9
  • Are there any other issues with std::reference_wrapper? If not, why not just implement your own version with everything included but the operator overload for copy assignment? Commented Dec 12, 2015 at 5:06
  • @JoelCornett Yes, there are other issues, since my reference emulator needs to have the same semantics as a real reference I need to overload operator& to return the same as &a, that is (something convertible to) a pointer to the original object. But I left that out of the question. (In fact I have to overload a lot of operators to make it behave like a real reference and even operator. if that were possible.) open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4173.pdf Commented Dec 12, 2015 at 5:22
  • @JoelCornett, Yes, I can implement my own but there are so many details to take into accout that I wondered if such thing existed already. Commented Dec 12, 2015 at 5:22
  • 1
    Your code shouldn't compile. You're comparing pointer-to-double with double. Commented Dec 12, 2015 at 6:39
  • Yep, doesn't compile either assertion Commented Dec 12, 2015 at 7:21

1 Answer 1

2
template <typename T>
class Tref {
    std::tuple<T &> t;
public:
    template <typename... Args>
    Tref(Args&&... args): t(std::forward<Args>(args)...) {}
    operator T &() { return std::get<0>(t); }
    decltype(&std::get<0>(t)) operator&() { return &std::get<0>(t); }
};


Tref<double &> t(a);
t = b;
assert(&t != &b);

What std::reference_wrapper does is binding when the template erase the reference. You needn't build a class to meet your needs, and just use normal reference. (I may not describe clearly. My English is poor.)

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, Do you find any advantage on using a std::tuple<T&> instead of class Tref{T& t;.... I have a similar implementation but I am undesided between using a pointer (like std::reference_wrapper does) or a reference. (a pointer is more flexible.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.