Bracket Overload for Assignment and Retrieval; const, reference - c++

Regarding overloading brackets in C++, my compiler is using the mutator method for access. Can anyone tell me why?
1. const int & Cheese::operator [] (int i)const { return weight[i]; } //accessor
2. int & Cheese::operator [] (int i) { return weight[i]; } //mutator
For example, the cout command below is using the mutator function definition--#2 above--to access the data.
Cheese cheddar;
cout << cheddar[2] << endl;
Why is this not using the first function--the accessor--to get the data? I would think that, since the cout is simply a retrieval, it would fire on the first.
How does the compiler know which of these to invoke?
EDIT: For completeness, by mutator, I mean used as a "setter," like so:
cheddar[2] = 100;
Both together would be as follows:
cheddar[2] = cheddar[1];
Where the rhs is just a "getter." It simply retrieves the value of cheddar[1], does not change anything, and thus can be const. In contrast, the lhs bracket overload cheddar[2] functions as a "setter;" the value can be changed, and function return value can't be const.

It invokes the first one for any constant instance (like const Cheese or const Cheese&) and the second one for mutable instances.

In case you care about a way you can get roughly the effect you seem to want (specifically, to have one function executed to get the value, and other code to set the value, dependably), there is a way to do that.
The usual way is to return a proxy instead of returning the value (or a reference to it) directly. The proxy overloads operator T and operator=.
template <class T>
class Proxy {
T value;
public:
Proxy(T v) : value(v) {}
// used only to get value
operator T() const { return value; }
// used only to set value
Proxy &operator=(T new_value) {
value = new_value;
return *this;
}
};
Then your overload just returns an instance of this:
Proxy<Cheese &> operator[](int i) { return Proxy<int>(weight[i]); }
Proxy<Cheese const &> operator[](int i) const { return Proxy<int>(weight[i]); }
Note that in the second case, T has the type Cheese const & and operator= isn't a const member function, so you won't be able to use operator= in this case (which is exactly what you normally want).

Related

Using std::variant<T, std::function<T()>> as a flexible input instead of subclassing

I have a class which takes an input, and sometimes I'd like to set that input by assigning a variable, and at other times I'd like the class to call a function to get its input.
In the past, I'd have just used a std::function<T()> as the input, and set a lambda to return the value of some external variable, but I'm trying to wean off an overuse of std::function. So I came up with std::variant<T, std::function<T()>>:
template <typename T>
using functionable = std::variant<T, std::function<T()>>;
// return the T or the result of the T() from the variant
template <typename T>
T get(const functionable<T>& f) {
if (f.index() == 0)
return std::get<0>(f);
else
return std::get<1>(f)();
}
Implemented thus:
class SomeClass {
private:
functionable<int> input_{0};
public:
SomeClass(const functionable<int>& input) : input_{input} {}
SomeClass& operator=(const functionable<int>& rhs) {
input_ = rhs;
return *this;
}
void print() { std::cout << get(input_) << '\n'; }
And used flexibly thus:
SomeClass foo {42}; // init with assigned value
foo.print();
foo = 101; // overwrite assigned value
foo.print();
bool a{true};
// replace input value with input lambda
foo { [this]{if(a) return 10; else return 20;} };
foo.print();
a = !a; // useful if input predicates change
foo.print();
foo = 101; // replace std::function input with assigned int
foo.print();
Is this an improvement over solely using a std::function<T()> for the input and using foo = []{return 42;} for fixed input values?
An alternative would be to make separate subclasses for assigned vs called inputs but that resulted in combinatorial explosion when there's more than one input. Are there other alternatives I'm missing?
Mathematically speaking, the constant function is just another function. And in this C++ example, there seems to be no motivating reason to treat the constant function as a special case. Performance is likely to be approximately the same, unless the large majority of your inputs are constants.
Additionally, this functionable cannot be used with std::generate, while a std::function<> wrapping a constant can. That's fixable of course by wrapping functionable in a class of its own or capturing one in another lambda. But it's just adding complexity when the simple solution will do.

int wrapper without overloading all the operators

I would like to have an int wrapper class that behaves like int without the need to overload all of the operators. The same question was asked but not really answered here. I know I can write a template wrapper and overload dozens of operators to achieve that (in fact, I have it like that now - basically it looks like this mess). However it would be nice if it would be possible to somehow expose the internal primitive type without the need to overload the operators that just forward the call to it.
Is that possible? Perhaps by overloading dereferencing operators or somesuch?
EDIT: Example code:
template<typename T>
class IDWrapper
{
public:
inline IDWrapper() { }
inline IDWrapper(T id) : m_Value(id) { }
constexpr static int size() { return sizeof(T); }
constexpr static T min() { return std::numeric_limits<T>::min(); }
constexpr static T max() { return std::numeric_limits<T>::max(); }
inline bool isValid() const { return m_Value != 0; }
inline operator T() const { return m_Value; }
inline operator T&() { return m_Value; } //this line was the attempt to make it transparent... unsuccessfully
inline IDWrapper &operator=(T v) { m_Value = v; return *this; }
inline void invalidate() { m_Value = 0; }
private:
T m_Value = 0;
};
Basically it wraps an ID of type T in a "special" way so that it gives convenient options for validating and invalidating it. Plus it gives convenient access the the size and min/max. The reason for the templated wrapper is that I will need to replace it later with base64 number or some other non-standard number type and I need the interface that relies on the IDWrapper to stay consistent. The numerical operators will still be provided by T so when I spell them out here I am just forwarding the call hence the question.
So I have fiddled with it inspired by the comments to the OP and it seems that having these two (and only these two) overloaded operators can do the trick:
operator T&() { /*...*/ }
operator const T&() const { /*...*/ }
Naturally it is not without the cost. For example if T is an int (or any type for which sizeof(T) < sizeof(void*)) then returning const reference to it is more expensive than doing a copy (but having a copy operator breaks the transparency). Not to mention memory address lookup. I am not sure about potential other problems with this so feel free to comment/answer. But this works.

Overload Class Instance Variable

I've been looking for this for a bit and haven't had any luck. May be that I'm searching for the wrong words, or perhaps it's an unusual request (Or simply not doable).
Regardless, my question: I want to be able to use an instance of a class... well, here's a very simple example:
class attribute
{
float value;
float min;
float max;
}
attribute attr1;
attr1.value = 5.0f;
Now, basically, I want to use attr1 as if I'm calling
attr1.value
So when I, say,
std::cout << attr1 << std::endl;
It would print 5.0 (Or just 5).
Thanks!
You need to implement
std::ostream& operator<<(std::ostream& os, attribute const& att)
{
os << att.value;
return os; // this is how you "chain" `<<`
}
Either permit att.value through public, friendship, or write a function.
Another alternative would be to build a cast operator to float:
class attribute
{
public:
operator float() const
{
return value;
}
private:
/*the rest of your class here*/
But this could introduce unexpected ambiguities.
Finally, if you want attribute to behave like a numeric type, then you can overload more operators as you see fit. For example, to overload +=, you could write
template<typename Y>
attribute& operator+=(const Y& p)
{
value += p;
return *this;
}

C++ Explain "one liner" constructor that overloads member function Iterator(int i = 0) : i(i) { };

I have a question about what this contractor is actually doing. I found it online and it works for my purpose, but I wish to understand its notation.
class Iterator {
int i;
public:
Iterator(int i = 0) : i(i) {};
friend class SinglyLinkedList<Element>;
Node* _current;
Iterator(SinglyLinkedList& list) {
this->list = list;
reset();
}
void reset() {
_current = list._head;
}
void next(){
if(!done()) {
_current = _current->_next;
}
}
bool done(){
bool done = false;
if(_current->_next == nullptr) {
done = true;
}
return done;
}
private:
SinglyLinkedList list;
};
This is a member function that proves it works.
unsigned long print(Element e, const Iterator& index) {
cout << index.i << "\n";
return 0;
When const Iterator& index = 2. The function outputs 2.
If you ignore the part about Element e, the basic idea is that I can use Iterator(SinglyLinkedList& list) and Iterator(int i = 0), both. And you can access the integer attribution by using index.i?
Any general insight is also appreciated.
The constructor
Iterator(int i = 0) : i(i) {}
lets you construct an instance of an iterator in three ways:
You can use this constructor without passing arguments (in which case zero is assumed)
You can call this constructor explicitly, passing it a single int argument, or
You can call this constructor implicitly, passing an int instead of it.
Here is the first way:
Iterator one;
Here is the second way:
Iterator two(123);
Here is the third way:
Iterator three = 321;
Back to your code, when you write this
const Iterator& index = 2;
the compiler creates a temporary object, initializes it using the implicit invocation of your constructor, and sets the reference of this temporary object into index. This is similar to the third kind of invocation of the constructor (i.e. the implicit one) but the target is a hidden, temporary object. The compiler is allowed to use a temporary here, because the index is declared const; it wouldn't compile without it.
dasblinkenlight's answer
explains the different ways this can be used, but I want to talk about what's actually going on here.
The line is Iterator(int i = 0) : i(i) {}; Let's break down all the pieces.
Iterator(int i=0) does three things:
Announces that this is a constructor for the Iterator class
Announces that this constructor takes a single int argument
Provides a default value for the single argument. In other words, the constructor calls Iterator() and Iterator(0) will have the same result
: i(i) is an initializer list. It assigns the member variable i (That's the first i) to the value of the parameter i (The i in brackets).
{}; is the body of the constructor. Nothing else is happening here, so it's been left empty.
A more verbose way of writing the same thing would be the following:
Iterator(){
i = 0;
}
Iterator(int index){
i = index;
}
That block and the line you've provided will have essentially the same result in most cases, although I don't know enough about the intricacies C++ to know if the above will work for some of the interesting cases you have (Like const Iterator& index = 2)

What is purpose of a "this" pointer in C++? [duplicate]

This question already has answers here:
When should I make explicit use of the `this` pointer?
(12 answers)
Closed 6 years ago.
What is purpose of this keyword. Doesn't the methods in a class have access to other peer members in the same class ? What is the need to call a this to call peer methods inside a class?
Two main uses:
To pass *this or this as a parameter to other, non-class methods.
void do_something_to_a_foo(Foo *foo_instance);
void Foo::DoSomething()
{
do_something_to_a_foo(this);
}
To allow you to remove ambiguities between member variables and function parameters. This is common in constructors.
MessageBox::MessageBox(const string& message)
{
this->message = message;
}
(Although an initialization list is usually preferable to assignment in this particular example.)
Helps in disambiguating variables.
Pass yourself as a parameter or return yourself as a result
Example:
struct A
{
void test(int x)
{
this->x = x; // Disambiguate. Show shadowed variable.
}
A& operator=(A const& copy)
{
x = copy.x;
return *this; // return a reference to self
}
bool operator==(A const& rhs) const
{
return isEqual(*this, rhs); // Pass yourself as parameter.
// Bad example but you can see what I mean.
}
private:
int x;
};
Consider the case when a parameter has the same name as a class member:
void setData(int data){
this->data = data;
}
Resolve ambgiguity between member variables/functions and those defined at other scopes
Make explicit to a reader of the code that a member function is being called or a member variable is being referenced.
Trigger IntelliSense in the IDE (though that may just be me).
The expression *this is commonly used to return the current object from a member function:
return *this;
The this pointer is also used to guard against self-reference:
if (&Object != this) {
// do not execute in cases of self-reference
It lets you pass the current object to another function:
class Foo;
void FooHandler(Foo *foo);
class Foo
{
HandleThis()
{
FooHandler(this);
}
};
Some points to be kept in mind
This pointer stores the address of
the class instance, to enable pointer
access of the members to the member
functions of the class.
This pointer is not counted for
calculating the size of the object.
This pointers are not accessible for
static member functions.
This pointers are not modifiable
Look at the following example to understand how to use the 'this' pointer explained in this C++ Tutorial.
class this_pointer_example // class for explaining C++ tutorial
{
int data1;
public:
//Function using this pointer for C++ Tutorial
int getdata()
{
return this->data1;
}
//Function without using this pointer
void setdata(int newval)
{
data1 = newval;
}
};
Thus, a member function can gain the access of data member by either using this pointer or not.
Also read this to understand some other basic things about this pointer
It allows you to get around members being shadowed by method arguments or local variables.
The this pointer inside a class is a reference to itself. It's needed for example in this case:
class YourClass
{
private:
int number;
public:
YourClass(int number)
{
this->number = number;
}
}
(while this would have been better done with an initialization list, this serves for demonstration)
In this case you have 2 variables with the same name
The class private "number"
And constructor parameter "number"
Using this->number, you let the compiler know you're assigning to the class-private variable.
For example if you write an operator=() you must check for self assignment.
class C {
public:
const C& operator=(const C& rhs)
{
if(this==&rhs) // <-- check for self assignment before anything
return *this;
// algorithm of assignment here
return *this; // <- return a reference to yourself
}
};
The this pointer is a way to access the current instance of particular object. It can be used for several purposes:
as instance identity representation (for example in comparison to other instances)
for data members vs. local variables disambiguation
to pass the current instance to external objects
to cast the current instance to different type
One more purpose is to chaining object:
Consider the following class:
class Calc{
private:
int m_value;
public:
Calc() { m_value = 0; }
void add(int value) { m_value += value; }
void sub(int value) { m_value -= value; }
void mult(int value) { m_value *= value; }
int getValue() { return m_value; }
};
If you wanted to add 5, subtract 3, and multiply by 4, you’d have to do this:
#include
int main()
{
Calc calc;
calc.add(5); // returns void
calc.sub(3); // returns void
calc.mult(4); // returns void
std::cout << calc.getValue() << '\n';
return 0;
}
However, if we make each function return *this, we can chain the calls together. Here is the new version of Calc with “chainable” functions:
class Calc
{
private:
int m_value;
public:
Calc() { m_value = 0; }
Calc& add(int value) { m_value += value; return *this; }
Calc& sub(int value) { m_value -= value; return *this; }
Calc& mult(int value) { m_value *= value; return *this; }
int getValue() { return m_value; }
};
Note that add(), sub() and mult() are now returning *this. Consequently, this allows us to do the following:
#include <iostream>
int main()
{
Calc calc;
calc.add(5).sub(3).mult(4);
std::cout << calc.getValue() << '\n';
return 0;
}
We have effectively condensed three lines into one expression.
Copied from :http://www.learncpp.com/cpp-tutorial/8-8-the-hidden-this-pointer/
Sometimes you want to directly have a reference to the current object, in order to pass it along to other methods or to store it for later use.
In addition, method calls always take place against an object. When you call a method within another method in the current object, is is equivalent to writing this->methodName()
You can also use this to access a member rather than a variable or argument name that "hides" it, but it is (IMHO) bad practice to hide a name. For instance:
void C::setX(int x)
{
this->x = x;
}
For clarity, or to resolve ambiguity when a local variable or parameter has the same name as a member variable.
It also allows you to test for self assignment in assignment operator overloads:
Object & operator=(const Object & rhs) {
if (&rhs != this) {
// do assignment
}
return *this;
}
It also allows objects to delete themselves. This is used in smart pointers implementation, COM programming and (I think) XPCOM.
The code looks like this (excerpt from some larger code):
class counted_ptr
{
private:
counted_ptr(const counted_ptr&);
void operator =(const counted_ptr&);
raw_ptr_type _ptr;
volatile unsigned int _refcount;
delete_function _deleter;
public:
counted_ptr(raw_ptr_type const ptr, delete_function deleter)
: _ptr(ptr), _refcount(1), _deleter(deleter) {}
~counted_ptr() { (*_deleter)(_ptr); }
unsigned int addref() { return ++_refcount; }
unsigned int release()
{
unsigned int retval = --_refcount;
if(0 == retval)
>>>>>>>> delete this;
return retval;
}
raw_ptr_type get() { return _ptr; }
};
The double colon in c++ is technically known as "Unary Scope resolution operator".
Basically it is used when we have the same variable repeated for example inside our "main" function (where our variable will be called local variable) and outside main (where the variable is called a global variable).
C++ will alwaysexecute the inner variable ( that is the local one).
So imagine you want to use the global variable "Conundrum" instead the local one just because the global one is expressed as a float instead of as an integer:
#include <iostream>
using namespace std;
float Conundrum=.75;
int main()
{
int Conundrum =75;
cout<<::Conundrum;
}
So in this case the program will use our float Conundrum instead of the int Conundrum.