One way modification of reference variables - c++

For example, I have this code.
#include <iostream>
using namespace std;
int main()
{
int x = 5; //Original variable
int &y = x; //Reference variable to x.
y = 10; //Modifying reference variable.
cout<<x<<" "<<y<<endl;
x = 5; //Modifying original variable.
cout<<x<<" "<<y<<endl;
}
It gives the expected output.
10 10
5 5
Shows that modifying either the original variable or the reference variable changes them both - Pretty obvious.
My question is that:
Can a reference variable be defined in such a way that modifying it DOES NOT modify the original variable?
I know then it wouldn't be called a reference variable.
To make things more clear,
Modifying x should modify y, but modifying y should not modify x. That is, y should be an independent copy of x, but should change as and when x changes.
Can this be possible?
Yes, I can create my own logic to emulate this, but I was wondering if C++ catered to this by default.

There is no language construct that can immediately give you what you seek but you can implement it fairly straightforward by encapsulating x and y.
struct XChangesY{
set_x(int x_and_y){ y = x = x_and_y; }
set_y(int y_){ y = y_; }
int get_x(){ return x; }
int get_y(){ return y; }
private:
int x;
int y;
}

No, what you want to do isn't possible. Consider what happens if you modify both y and x. Where does y take its value then? From the updated value of x which should modify both x and y, or from the updated value of y which should update y only and not x?
The only way forward is to implement your own logic. In any case, you need to have two int variables.

Sure, but it's not elegant--
template<typename T>
class C
{
public:
C(T t) : m_t(new T(t)), t_local(t), is_copy(false) {}
C(const C& c) : m_t(c.m_t), t_local(t), is_copy(true) {}
T Get() { return *m_t; }
T GetLocal() { return t_local; }
void Set(T t)
{
t_local = t;
if (!is_copy) *m_t = t;
}
private:
T* m_t;
T t_local;
bool is_copy;
};
And your setup creates an ambiguity when it comes to evaluating y, after both it has been changed--do you want the value of x, or the new, different value of y? I don't see any way to avoid creating separate methods for each case.

C++ does not provide a mechanism for doing this automatically, but you can make a class that supports the behavior that you are trying to make.
Here is a grossly oversimplified version of what you can do:
class IntRef {
int *ptr;
int copy;
public:
IntRef(int& d) : ptr(&d) {}
IntRef& operator=(const int& rhs) {
// Detach from the original on assignment
copy = rhs;
ptr = ©
}
operator int() const {
return *ptr;
}
};
int main() {
int x = 5; //Original variable
IntRef y(x); //Reference variable to x.
x = 5; //Modifying original variable.
cout<<x<<" "<<y<<endl;
y = 10; //Modifying reference variable.
cout<<x<<" "<<y<<endl;
return 0;
}
Demo.
This prints
5 5
5 10
The idea of the implementation above is to keep a pointer pointing to the original value for as long as y is not assigned. After the assignment the pointer is switched to a copy that is kept internally.

What you're looking for isn't inherently built-in the language - having two variables sharing the same value, changing one changes both but changing the other one only changes one.
That question though is similar to shared pointers and reference counters. For example, when you make a copy of a std::string, the content of the string isn't copied. A new string object is created with a pointer to the same data as the first string, and a reference counter.
So both strings share the same data. But when you change one - either one - and the reference counter is more than one, then that string dissociates itself and copies the data, and both strings are no longer linked. This is in order to avoid duplicated long strings of data when there's no need.
The same thing happens with Qt containers (QByteArray, QMap, QList, ...).
Another way to look at your problem is a logic of watcher - data received from outside updates the internal value, but the internal value can be changed by other means. Qt's signals/slot feature can be used to do that naturally, or you can easily implement your own logic to do that yourself.

Seems like what you want is copy-on-write semantics. Something like this might work for you, but is easily abused:
template <class T>
class cow_ptr
{
public:
using ref_ptr = std::shared_ptr<T>;
private:
ref_ptr m_sp;
bool m_original; //don't detach the original
void detach()
{
T* tmp = m_sp.get();
if( !( tmp == 0 || m_sp.unique() || m_original ) ) {
m_sp = ref_ptr( new T {*tmp} );
}
}
public:
cow_ptr(T* t)
: m_sp{t}, m_original{true}
{}
cow_ptr(const ref_ptr& refptr)
: m_sp{refptr}, m_original{true}
{}
cow_ptr(const cow_ptr& cowptr)
: m_sp{cowptr.m_sp}, m_original{false}
{}
cow_ptr& operator=(const cow_ptr& rhs)
{
m_sp = rhs.m_sp;
return *this;
}
const T& operator*() const
{
return *m_sp;
}
T& operator*()
{
detach();
return *m_sp;
}
const T* operator->() const
{
return m_sp.operator->();
}
T* operator->()
{
detach();
return m_sp.operator->();
}
};
Then you can use it like this:
int main()
{
auto x = cow_ptr<int>{ new int{5} };
auto y = x;
const auto &yr = y; //so dereferencing doesn't detach
cout<<*x<<" "<<*yr<<endl; //5 5
*x = 10;
cout<<*x<<" "<<*yr<<endl; //10 10 (updating x updated y)
*y = 15;
cout<<*x<<" "<<*yr<<endl; //10 15 (updating y did not update x)
//from now on, changing x will not change y
}

Related

Struct with array that changes dynamically

I have been looking to change dynamically the values of an array in a struct depending on other variables of the struct.
Let's say I have:
struct foo
{
int value1 = 0;
int value2 = 0;
int arr[2] = {value1, value2};
};
In the main if I have create an instance fooInstance and I want to associate a value to value1 fooInstance.value1 = 10, how can I update the value in the array ?
Thank you for your time.
Firstly, if you need an array, then I recommend storing the objects in the array directly.
I question the value (i.e. usefulness) of these aliases such as value1 when the name has no more meaning than referring to arr[i] directly. But I can see the value in case there is a descriptive name available. I'll use a more meaningful example of 2D vector with x, y dimensions. It should be easy to change float to int and change the names to match your attempt.
While Frank's solution using functions is great in most regards, it has a small caveat of having a less convenient syntax compared to variables. It's possible to achieve the variable syntax using operator overloading and anonymous unions. The trade-off is the increased boilerplate in the class definition. Example:
union Vector2 {
struct {
float a[2];
auto& operator=(float f) { a[0] = f; return *this; }
operator float&() & { return a[0]; }
operator const float&() const & { return a[0]; }
operator float () && { return a[0]; }
float* operator&() { return &a[0]; }
} x;
struct {
float a[2];
auto& operator=(float f) { a[1] = f; return *this; }
operator float&() & { return a[1]; }
operator const float&() const & { return a[1]; }
operator float () && { return a[1]; }
float* operator&() { return &a[1]; }
} y;
struct {
float a[2];
auto& operator=(float f) { a[0] = a[1] = f; return *this; }
float* begin() { return std::begin(a); }
float* end() { return std::end(a); }
} xy;
};
int main() {
Vector2 v2;
v2.xy = 1337; // assign many elements by name
v2.x = 42; // assign one element by name
std::cout << v2.x; // read one element by name
for(float f : v2.xy) { // iterate the entire array
std::cout << f;
}
}
Note to those unfamiliar with rules of unions: Reading from inactive union member is allowed only through common initial sequence of standard layout structs. This code is well defined, but the reader should be careful to not over generalise and assume that type punning through unions would be allowed; It isn't.
I adapted code from my earlier answer to another question.
It is different parameters coming from different hardwares.
This sounds like generating the accessors shown above with meta programming could be a good approach.
But, if you would like to avoid the complexity, then a more traditional approach would be to just use the array, and use enum to name the indices:
struct foo
{
int arr[100];
enum indices {
name1,
name2,
// ...
name100,
name_count,
};
};
int main()
{
foo f;
f.arr[foo.name1] = 42;
}
If at all possible, use encapsulation. That's the preferred way to create an interface/implementation skew:
struct foo
{
int& value1() { return arr_[0]; }
int& value2() { return arr_[1]; }
int* arr() { return arr_; }
private:
int arr_[2] = {0, 0};
};
void bar(foo& v) {
// access a single value
v.value1() = 3;
// access the whole array
v.arr()[0] = 5;
}
If you need access through both the individual member variables and through an array member variable, do not copy the data; rather, use the array as "the source of truth", and provide access through the individual variables or the individual member functions.
Here is your example rewritten to "alias" array variables to scalar member variables:
struct foo
{
foo() : value1(arr[0]), value2(arr[1]) {}
std::array<int,2> arr;
int& value1;
int& value2;
};
Note: this is not a good way of doing anything in production code, just an illustration of how the language lets you do something like this. Normally I would add accessor member-functions instead of member-variable references, because it avoids many problems referenced in the comments, such as breaking the value semantics.

Return by const reference in c++ where the receiver function copy the value is it worth it?

i have this situation which i wander if returning by const reference dose relay save something , this function may be called hundreds of times .
i have :
General Container that returns int as const reference
struct Val
{
public:
Val(int& v)
{
iVal = v;
}
const int& toInt()
{
return iVal;
}
private:
int iVal;
};
function that getting the number:
Val Mo::doSomthing()
{
Val v(444444);
return v;
}
calling the doSomthing().toInt():
int x = 0;
class Foo {
...
....
Mo mo;
void Foo::setInt(float scaleX)
{
x = mo.doSomthing().toInt();
//x is class member which other functions are using it
}
...
...
..
}
In this case is there any reason to for using const reference to save some bits?
In general for scalar types it is cheaper to return them by value. A reference (and a pointer) has near the same size (word length) as an usual scalar type. If you return an int& you return ~the same amount of data, however when you access the data referenced the running platform has to resolve the reference (access the memory referenced).
But the previous comments are right: measure it first. It is a kind of micro optimization.

What is the lifetime of a C++ lambda expression?

(I have read What is the lifetime of lambda-derived implicit functors in C++? already and it does not answer this question.)
I understand that C++ lambda syntax is just sugar for making an instance of an anonymous class with a call operator and some state, and I understand the lifetime requirements of that state (decided by whether you capture by value of by reference.) But what is the lifetime of the lambda object itself? In the following example, is the std::function instance returned going to be useful?
std::function<int(int)> meta_add(int x) {
auto add = [x](int y) { return x + y; };
return add;
}
If it is, how does it work? This seems a bit too much magic to me - I can only imagine it working by std::function copying my whole instance, which could be very heavy depending on what I captured - in the past I've used std::function primarily with bare function pointers, and copying those is quick. It also seems problematic in light of std::function's type erasure.
The lifetime is exactly what it would be if you replaced your lambda with a hand-rolled functor:
struct lambda {
lambda(int x) : x(x) { }
int operator ()(int y) { return x + y; }
private:
int x;
};
std::function<int(int)> meta_add(int x) {
lambda add(x);
return add;
}
The object will be created, local to the meta_add function, then moved [in its entirty, including the value of x] into the return value, then the local instance will go out of scope and be destroyed as normal. But the object returned from the function will remain valid for as long as the std::function object that holds it does. How long that is obviously depends on the calling context.
It seems you're more confused about std::function than lambdas.
std::function uses a technique called type-erasure. Here's a quick fly by.
class Base
{
virtual ~Base() {}
virtual int call( float ) =0;
};
template< typename T>
class Eraser : public Base
{
public:
Eraser( T t ) : m_t(t) { }
virtual int call( float f ) override { return m_t(f); }
private:
T m_t;
};
class Erased
{
public:
template<typename T>
Erased( T t ) : m_erased( new Eraser<T>(t) ) { }
int do_call( float f )
{
return m_erased->call( f );
}
private:
Base* m_erased;
};
Why would you want to erase the type? Isn't the type we want just int (*)(float)?
What the type erasure allows is Erased can now store any value that is callable like int(float).
int boring( float f);
short interesting( double d );
struct Powerful
{
int operator() ( float );
};
Erased e_boring( &boring );
Erased e_interesting( &interesting );
Erased e_powerful( Powerful() );
Erased e_useful( []( float f ) { return 42; } );
This is:
[x](int y) { return x + y; };
Is equivalent to: (Or can be considered too)
struct MyLambda
{
MyLambda(int x): x(x) {}
int operator()(int y) const { return x + y; }
private:
int x;
};
So your object is returning an object that looks just like that. Which has a well defined copy constructor. So it seems very reasonable that it it can be correctly copied out of a function.
In the code that you posted:
std::function<int(int)> meta_add(int x) {
auto add = [x](int y) { return x + y; };
return add;
}
The std::function<int(int)> object that is returned by the function actually holds a moved instance of the lambda function object that was assigned to local variable add.
When you define a C++11 lambda that captures by-value or by-reference, the C++ compiler automatically generates a unique functional type, an instance of which is constructed when the lambda is called or assigned to a variable. To illustrate, your C++ compiler might generate the following class type for the lambda defined by [x](int y) { return x + y; }:
class __lambda_373s27a
{
int x;
public:
__lambda_373s27a(int x_)
: x(x_)
{
}
int operator()(int y) const {
return x + y;
}
};
Then, the meta_add function is essentially equivalent to:
std::function<int(int)> meta_add(int x) {
__lambda_373s27a add = __lambda_373s27a(x);
return add;
}
EDIT: By the way, I am not sure if you know this, but this is an example of function currying in C++11.

Return reference to sliced object (supertype)

Consider the following classes:
class Coord
{
public:
double _x, _y;
Coord(double x, double y)
{
_x = x;
_y = y;
}
};
class NamedPoint : public Coord
{
public:
int _id;
NamedPoint(int id, double x, double y) :
Coord(x,y),
_id(id)
{
}
};
I'd like to create a member function of NamedPoint -- coord() -- that returns a reference of type Coord corresponding to the NamedPoint.
For example, I'd like to something like:
const Coord& NamedPoint::coord()
{
return ((Coord)*this);
}
But I get a warning about temporary variables and I'm not crazy about it.
Of course, the following works:
Coord coord()
{
Coord c = *this;
return c;
}
But I'd rather return a reference.
Does anyone know if this is possible using inherited classes?
Sorry for not explaining the point of the function. I'm overloading the == operator differently for Coord and NamedPoint. Coord would simply check {x,y} and NamedPoint would check {id,x,y}. If I forget to cast a NamedPoint to a Coord before this == test, I'll use the wrong version.
So, while I realize that
(Coord)np1 == (Coord)np2
would give me what I want, I'd rather use something like
np1.coord() == np2.coord()
which I think is more clear as to what is going on.
What's the point of the function? NamedPoint is implicitly convertible to Coord anyway:
void foo(Coord& c)
{
c._x = 5;
}
NamedCoord nc(0, 1, 2);
foo(nc); // c references the Coord part of nc
Anyway, your function should simply use this conversion:
const Coord& NamedPoint::coord()
{
// Bad: takes the value of *this and slices off
// the derived bits, leaving a temporary Coord.
/* return ((Coord)*this); */
// Good: takes the value of *this and refers
// to the base bits, no temporaries.
return *this;
// (Same as:)
/* return ((Coord&)*this); */
}
#GMan gives the main solution.
However, it might be interesting to note in more detail the problem:
const Coord& NamedPoint::coord()
{
return ((Coord)*this);
}
This is much the same as:
const Coord& NamedPoint::coord()
{
Coord c = *this;
return c;
}
Here it is clear that you are returning a reference to a temporary on the stack, which makes the reference to it useless, and hence the warning.
Now in the case presented, Coord is the base class and hence we have the simple solution given by #Gman.
In the general case, the principle is that if you want a reference to something, you better make sure that something will still be around.

C++ union array and vars?

There's no way to do something like this, in C++ is there?
union {
{
Scalar x, y;
}
Scalar v[2];
};
Where x == v[0] and y == v[1]?
Since you are using C++ and not C, and since they are of the same types, why not just make x a reference to v[0] and y a reference to v[1]
How about
union {
struct {
int x;
int y;
};
int v[2];
};
edit:
union a {
struct b { int first, second; } bee;
int v[2];
};
Ugly, but that's more accurate
Try this:
template<class T>
struct U1
{
U1();
T v[2];
T& x;
T& y;
};
template<class T>
U1<T>::U1()
:x(v[0])
,y(v[1])
{}
int main()
{
U1<int> data;
data.x = 1;
data.y = 2;
}
I've used something like this before. I'm not sure its 100% OK by the standard, but it seems to be OK with any compilers I've needed to use it on.
struct Vec2
{
float x;
float y;
float& operator[](int i) { return *(&x+i); }
};
You can add bounds checking etc to operator[] if you want ( you probably should want) and you can provide a const version of operator[] too.
If you're concerned about padding (and don't want to add the appropriate platform specific bits to force the struct to be unpadded) then you can use:
struct Vec2
{
float x;
float y;
float& operator[](int i) {
assert(i>=0);
assert(i<2);
return (i==0)?x:y;
}
const float& operator[](int i) const {
assert(i>=0);
assert(i<2);
return (i==0)?x:y;
}
};
I was looking for a similair thing and eventually came up with a solution.
I was looking to have a data storage object that I could use as both an array of values and as individual values (for end-user flexibility in writing Arduino libraries).
Here is what I came up with:
class data{
float _array[3];
public:
float& X = _array[0];
float& Y = _array[1];
float& Z = _array[2];
float& operator[](int index){
if (index >= 3) return _array[0]; //Make this action whatever you want...
return _array[index];
}
float* operator&(){return _array;}
};
int main(){
data Test_Vector;
Test_Vector[0] = 1.23; Test_Vector[1] = 2.34; Test_Vector[2] = 3.45;
cout<<"Member X = "<<Test_Vector.X;
cout<<"Member Y = "<<Test_Vector.Y;
cout<<"Member Z = "<<Test_Vector.Z;
float* vector_array = &Test_Vector;
cout<<"Array = {"<<vector_array[0]<<", "<<vector_array[1]<<", "<<vector_array[2]<<"}";
}
Thanks to Operator overloading, we can use the data object as if was an array and we can use it for pass-by-reference in function calls (just like an array)!
If someone with More C++ experience has a better way of applying this end product, I would love to see it!
EDIT: Changed up the code to be more cross-platform friendly
Given your example:
union
{
struct
{
Scalar x, y;
};
Scalar v[2];
};
As others have noted, in general, the standard does not guarantee that there will be no padding between x and y, and actually compilers inserting padding in structures is pretty common behavior.
On the other hand, with solutions like:
struct U
{
int v[2];
int& x;
int& y;
};
U::U()
: x(v[0])
, y(v[1])
{}
what I don't like mainly is the fact that I have to mention x, y twice. For cases where I have more than just a few elements (say 10), this becomes much less readable and harder to maintain - e.g. if you want to change the order of x,y then you have to change the indexes below too (well not mandatory but otherwise order in memory wouldn't match order of fields, which would not be recommended). Also, U can no longer be a POD since it needs a user-defined constructor. And finally, the x & y references consume additional memory.
Hence, the (acceptable for me) compromise I've come up with is:
struct Point
{
enum CoordType
{
X,
Y,
COUNT
};
int coords[CoordType::COUNT];
};
typedef Point::CoordType PtCoord;
With this you can then do:
Point p;
for ( int i = 0; i < PtCoord::COUNT; i++ )
p.coords[i] = 100;
std::cout << p.coords[PtCoord::X] << " " << p.coords[PtCoord::Y] << std::endl;
// 100 100
A bit sophisticated but I prefer this over the references suggestion.
Depending on what "Scalar" is, yes, you can do that in C++. The syntax is almost exactly (maybe even exactly exactly, but I'm rusty on unions) what you wrote in your example. It's the same as C, except there are restrictions on the types that can be in the unions (IIRC they must have a default constructor). Here's the relevant Wikipedia article.
With C++11 you have anonymous unions and structs which just export their definitions to the enclosing scope, so you can do this:
typedef int Scalar;
struct Vector
{
union
{
struct
{
Scalar x, y;
};
Scalar v[2];
};
};