C++ - Unable to overload assignment operator [duplicate] - c++

This question already has answers here:
The assignment operator and initialization
(2 answers)
Closed 6 years ago.
I am trying to overload the assignment operator but it doesn't seem to work. The code is based on this answer. I've searched for other examples of overloading the assignment operator, but it doesn't seem like my code shouldn't run.
This is my code:
#pragma once
#include <assert.h>
class ReadOnlyInt
{
public:
ReadOnlyInt(): assigned(false) {}
ReadOnlyInt& operator=(int v);
operator int() const ;
private:
int value;
bool assigned;
};
ReadOnlyInt& ReadOnlyInt::operator=(int v)
{
assert(!assigned);
value = v;
assigned = true;
return *this;
}
ReadOnlyInt::operator int() const
{
assert(assigned);
return value;
}
Intellisense doesn't give any warnings, but the operator= is not highlighted as a keyword.
Now if I make an assigment, Intellisense does recognize it's not possible:
ReadOnlyInt bar = 12;
no suitable constructor exists to convert from "int" to "ReadOnlyInt"
This works however:
int foo = bar;
Solution
This question was marked as duplicate, so I can't answer it. This was the solution I came up with based on the comments and answer on this question:
ReadOnlyInt::ReadOnlyInt()
: assigned(false)
{}
ReadOnlyInt::ReadOnlyInt(int v)
: value(v), assigned(true)
{}

You can't initialize and declare at the same time. You need to do this
ReadOnlyInt bar;
bar = 12;
This is because there is no appropriate constructor for ReadOnlyInt that takes an int argument.

Related

Replacing Implicitly-Deleted Operator With Template Method [duplicate]

This question already has answers here:
Template assignment operator doesn't replace the default assignment operator
(2 answers)
Template assignment operator overloading mystery
(2 answers)
Closed 4 years ago.
Consider the following code:
class Foo { public:
int const i;
Foo() : i(0) {}
};
void test() {
Foo a;
Foo const b;
a = b; //Failure here; `Foo::operator=` implicitly deleted
}
The indicated line fails because the operator= ordinarily generated by the compiler cannot be generated: .i is marked const. This is good and expected.
The programmer can generate their own operator=, so long as it does not change .i. E.g. this method does nothing:
Foo& operator=(Foo const& other) {
return *this;
}
But now, suppose I want to be more-general. I templatize the method:
template <typename TypeOther>
Foo& operator=(TypeOther const& other) {
return *this;
}
Suddenly, I get back the original failing behavior (tested Clang, GCC, and MSVC)! It seems that, even though the default operator= is not generated, it participates in overload resolution and therefore is selected instead of the template variant.
Why is the implicit operator is being selected even though it does not exist (i.e, is it as if I had just written and deleted it myself—that is, it exists but is forbidden)?
How I can work around this to make my template operator= be selected for any type?

C++: Bilateral class conversion [duplicate]

This question already has answers here:
What are the basic rules and idioms for operator overloading?
(8 answers)
Closed 6 years ago.
Let's say, I have two simple classes: integer with just one int variable in it, and real with double. I'm already done so that
integer a=2016;
int b=a;
real a=20.16;
double b=a;
working perfectly. Now I have to do the conversion between them, like so:
integer foo; real bar;
foo=bar;
bar=foo;
Or at least with similar syntax. I know that there will be loss of some data when converting double to int, I'll deal with it. So how can I do that? What and where should I #include and what the methods/operator overloads to write? My project is divided into files main.cpp, integer.h, integer.cpp, real.h, real.cpp. Thanks.
EDIT: The classes looks like:
//integer.h
class integer
{
private:
int a;
public:
integer();
integer(int number);
operator int() const;
};
//integer.cpp
#include "integer.h"
integer::integer(){
a=0;
}
integer::integer(int number){
a=number;
}
integer::operator int() const{
return a;
}
//real.h
class real {
private:
double a;
public:
real();
real(double number);
operator double() const;
};
//real.cpp
#include "real.h"
real::real(){
a=0;
}
real::real(double number){
a=number;
}
real::operator double() const{
return a;
}
You basically have two solutions to your problem:
The first is to write conversion operators that can convert a real object to an integer object, and vice versa.
The other solution is to implement custom constructors and assignment operators to take the other class.

c++ left hand assignment operator [duplicate]

This question already has answers here:
Why cannot a non-member function be used for overloading the assignment operator?
(9 answers)
Closed 7 years ago.
i have a class (wich should hold any value) like this:
class Value
{
public:
Value();
Value(const Value& value);
virtual ~Value();
void operator= (const Value& value);
template<class T>
void operator= (T value);
...
}
now my question:
why can't i implement an assignment operator for this class like this:
template<class T>
void operator=(T& value, const Value& v)
{...}
I wan to desing a class wich works the following:
Value v;
v = 'c';
v = 13;
v = 5.6;
int i = 5;
v = &i;
int y = v;
char b = v;
i want to put any datatype into it and out of it.
at the moment this works fine for:
v = 'c';
v = 13;
v = 5.6;
but not for:
int y = v;
what works is:
int y = v.get<int>();
but this is not as nice as
int y = v;
would be
You can easily fix the compilation error by adding template type cast to your class like following:
class Value
{
...
template <class T> operator T();
};
Value va;
int i = va;
I still believe you will find the task of implementing 'boost::any' yourself quite challenging, but why not? :)
Because the standard says that an assignment operator must be a member function with only one parameter.
13.5.3$1 Assignment [over.ass]:
An assignment operator shall be implemented by a non-static member function with exactly one parameter.
You can implement a typecast operator like this
operator int()
{
if(current_value_is_not_int)
throw MyException("Current value is not int");
//return int value
}

Is it possible to use a friend function to convert a class-type a basic-type? [duplicate]

This question already has answers here:
Non-member conversion functions; Casting different types, e.g. DirectX vector to OpenGL vector
(3 answers)
Closed 8 years ago.
Is it possible using friends?
class MyClass
{
private:
int myInteger;
float myFloat;
public:
void SetData(int a, float b)
{
myInteger = a;
myFloat = b;
}
operator int();
friend operator float(MyClass & );
};
MyClass :: operator int()
{
return myInteger;
}
operator float(MyClass & obj)
{
return obj.myFloat;
}
This code doesn't compile. How to do it in a correct way?
VS2008 says:
error C2801: 'operator float' must be a non-static member
Why not making op float a member?
operator float(){ return myFloat;}
If overloading the operator isn't working for you, consider using a named function:
float ToFloat(MyClass & obj)
{
return obj.myFloat;
}
This will also avoid implicit conversions... but I suppose if you were planning on overloading the operator your intention was to allow the implicit conversion.

"Explicit" preventing automatic type conversion? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does the explicit keyword in C++ mean?
I do not understand the following. If I have:
class Stack{
explicit Stack(int size);
}
without the keyword explicit I would be allowed to do:
Stack s;
s = 40;
Why would I be allowed to do the above if explicit wasn't provided?? Is it because this is stack-allocation (no constructor) and C++ allows anything to be assigned to the variable unless explicit is used?
This line
s = 40;
is equivalent to
s.operator = (40);
Which tries to match the default operator = (const Stack &). If the Stack constructor is not explicit, then the following conversion is tried and succeeds:
s.operator = (Stack(40));
If the constructor is explicit then this conversion is not tried and the overload resolution fails.
hey its pretty simple .
the explicit key word only stops complier from automatic conversion of any data type to the user defined one.. it is usually used with constructor having single argument .
so in this case u are jus stopping the complier from explicit conversion
#include iostream
using namespace std;
class A
{
private:
int x;
public:
A(int a):x(a)
{}
}
int main()
{
A b=10; // this syntax can work and it will automatically add this 10 inside the
// constructor
return 0;
}
but here
class A
{
private:
int x;
public:
explicit A(int a):x(a)
{}
}
int main()
{
A b=10; // this syntax will not work here and a syntax error
return 0;
}