ARTICLE AD BOX
I'm replacing a method returning a reference with a method returning a pseudo-reference.
Given a method Get() that used to return a reference, this code has a problem:
auto value = Object.Get();value becomes a copy of the object when Get returns a reference. When it returns a pseudo-reference type, value becomes a copy of the pseudo-reference, a significant change in semantics.
One possible solution would be to make the "usual" ways of creating a copy of the object in automatic storage not work. Prior to guaranteed elision, I could just block all copy and move constructors for the type. Then the pseudo-reference would simply refuse to compile with the above code.
But with guaranteed elision, my Get method that returns a pseudo-reference gets elided into automatic storage, and it outlives the length of time I intended it to. What more, it changes semantic meaning at that site, from storing a copy to storing a possibly dangling reference.
Blocking auto deduction of the type would also work, but I don't think that is allowed.
Having a solution to either of these would solve my problem. I don't think there is a solution, so here is my overarching problem I'm hoping to solve (to avoid X/Y issues):
The concrete problem I'm trying to solve is that I have a property box type that maps keys to any's, sort of like this:
struct Properties { std::any& operator[](std::string key); };I want to change it to:
struct Properties { custom_any_pseudo_ref_type operator[](std::string key); };and have code that won't play nice with this change (ie works before, dangerous after) break the build, but code that will pay nice to just compile untouched.
Stepping back one further in what I want, I'm changing the Properties from owning a key-value map to having a copy-on-write copy of the key-value map, but much of the code using them isn't very const-correct; it often accesses non-const members freely when it only wants to read, as this wasn't expensive so nobody cared.
My any_pseudo_ref can distinguish between read and write access, and on write cause the copy-on-write code of the property box that owns it to get a writable version of the data before returning it, so code like:
Properties box; box["a"] = 7; // ... // much later, a read: std::cout << get_value_or<int>(box["a"], 0) << "\n";won't trigger a copy-on-write on the read code, without having to be touched, despite [] being called in a non-const context.
Maybe I just need a good C++ refactoring tool to detect when a method is stored in an auto variable instead of making the compiler do it for me?
Implicit Evaluation of “auto” Variables seems to be aimed at my problem, but wasn't added to the standard. Is there a workaround?
