, ++ .
, Transform - . - , . - , , .
:
struct Proxy {
OriginalObject& ref;
bool copied;
operator OriginalObject() {
OriginalObject copy(ref);
transform copy;
copied := true;
return copy;
}
~Proxy() {
if (not copied)
transform original reference
}
};
Proxy Transform(OriginalObject& obj) { ... }
:
OriginalObject copy = Transform(myRef);
Transform(myRef);
{
auto cynicCopy = Tranform(myRef);
(myRef);
}
, , - . , , . .
#include <iostream>
#include <string>
template<typename T, typename Operation>
struct CynicTransform {
std::reference_wrapper<T> ref;
Operation op;
bool opDtor;
CynicTransform(T& r, Operation o)
:
ref(r),
op(o),
opDtor(true)
{ }
CynicTransform(const CynicTransform&) = delete;
CynicTransform& operator=(const CynicTransform&) = delete;
CynicTransform(CynicTransform&& ct)
:
ref(ct.ref),
op(ct.op),
opDtor(ct.opDtor)
{
ct.opDtor = false;
}
CynicTransform& operator=(CynicTransform&& ct) {
using std::swap;
swap(ref, ct.ref);
swap(op, ct.op);
swap(opDtor, ct.opDtor);
return *this;
}
~CynicTransform() {
if (opDtor) {
op(ref.get());
}
}
operator T() {
T copy(ref.get());
op(copy);
opDtor = false;
return copy;
}
};
template<typename T, typename Operation>
CynicTransform<T, Operation> MakeCynicTransform(T& tref, Operation op)
{
return CynicTransform<T, Operation>(tref, op);
}
auto Transform(std::string& strRef)
{
return MakeCynicTransform(strRef, [](std::string& strRef) {
strRef += " modified";
});
}
int main() {
std::string s("original");
std::cout << "Initially: " << s << std::endl;
std::string copy = Transform(s);
std::cout << "Original: " << s << std::endl;
std::cout << "Copy: " << copy << std::endl;
{
auto cynicCopy = Transform(s);
std::cout << "Scope Original: " << s << std::endl;
}
std::cout << "Cynic Modified: " << s << std::endl;
Transform(s);
std::cout << "At Last: " << s << std::endl;
}
Edit: I got inspiration from the specification std::asyncwhere, if you go back to the returned one std::future, then the method behaves wisely. But if you call std::asyncdirectly, it becomes a lock.
zahir source
share