I want to overload the operator = and I have the following operator-function
int IntegerClass::operator=(IntegerClass integer) {
return integer.number;
}
This should be correct?
In another class I want to assign the objects private member (int) to another int i.e.
int x = integerClass;
but when I compile I get the following error
error: cannot convert 'std::IntegerClass' to 'int' in initialization
What is wrong with my implementation of operator-overloading and how should the function look like?
Your operator overloads assignment of one IntegerClass to another, but you're trying to assign (actually it's initialization) to a built in int. You need to define an implicit conversion operator.
The code should be something like this (sorry I don't remember the exact syntax)
IntegerClass::operator int() {
return number;
}
Related
In the following C++ code, I am creating a class and declaring a private variable in that class.
#include <iostream>
class num{
int k;
public:
operator int(){
return k;
}
};
int main(){
num obj;
std::cout<<obj; // calls int()
return 0;
}
On execution, this code will print the value of 'k' in 'obj' of type num. That clearly indicates that the member function of the class num has been invoked somehow. The invoked member function has the header 'operator int()', so, how does this function get invoked since I have not operated on obj and just printed it's value ?
The compiler looks for a valid overload of
operator<<(std::ostream&, something);
Since
operator<<(std::ostream&, num const&);
is not defined/provided, it looks for any allowed alternatives. Since num allows implicit type conversion to int, this is used, creating code equivalent to
std::cout<<static_cast<int>(num);
In fact, this is the exact reason for providing such an type-conversion operator: the type (num in this case) can be used instead of the conversion type in (almost) any function call w/o the need for explicit type conversion.
The code
operator int(){
return k;
}
is a conversion of a num object to an int object. The conversion is implicit which means that it can be done automatically, i.e. even when you don't ask for it. In other words - if the compiler needs an int object but has a num object, the compiler will automatically call int() to convert num to an int.
Therefore you can do strange things like:
int n = 10 + obj;
and
void foo(int x)
{
....
}
foo(obj);
This goes even further... If the compiler needs a << but num doesn't provide one, the compiler sees that it can convert num to int and that int has a <<. Consequently the compiler decides to do that.
A personal opnion:
It might seem smart to be able to convert some type to another type automatically. However, it is also confusing - especially to your co-workers. Therefore I'll recommend to avoid implicit conversions. If you need a conversion make it explicity. Then there will be no nasty surprises.
I am using a library that is templated and that I do not wish to modify. Namely CImg.
This library has been mostly designed to work with templates of simple types: float, double, int etc.
At some point, this library does:
CImg<T>& fill(const T val) {
if (is_empty()) return *this;
if (val && sizeof(T)!=1) cimg_for(*this,ptrd,T) *ptrd = val;
else std::memset(_data,(int)val,size()*sizeof(T));
return *this;
}
Now I want to use this library with a more complex class as template parameter. My particular class is such that sizeof(T)!=1 and most of the time, the fill function will properly assign val to each element with the proper operator= of my class. However, when !val, I would like a conversion operator that allows my class to be cast to an int and to produce some values (for example, 0 would make the function above work).
Right now, my program does not compile as it says:
error C2440: 'type cast' : cannot convert from 'const MyClass' to 'int'
How can I create an operator that allows for (int)my_variable with my_variable of type MyClass to be legal, without modifying the function above ?
Something like this using user defined conversions
int type;
explicit operator int()
{
return type;
}
What you want in this case is probably int conversion operator overload:
class A{
public:
explicit operator int() const{
return 2;
}
};
EDIT:
|I added explicit conversion that should make your code compile (at least the method you showed us), and not mess-up other operators, but it's only allowed since C++11, so if you are using older compiler it might not be available yet.
I have a class named mc_int which is actually a int, with some special abilities. It has set operator int():
mc_int::operator int() {
return value; //int mc_int::value - the real int value of the class
}
But when I try to cout<< the class, I must always cast the class to int (cout<<(int)mc_int_instance, because I get the error:
More than one operator "<<" matches these operands.
As well, this may be caused by the fact, that the class also has << operator defined. What to do here?
If you're using C++11, you can make use of the explicit keyword to make it so you have to explicitly convert to int. More information here:
explicit mc_int::operator int()
Now when you use it should use the << operator method you defined and it should no longer be ambiguous to the compiler. If you do want to use the int, just cast to it like you did or with static_cast<int>(the_object).
I am trying to write bool-conversion operator for std::bitset
I tried:
template<size_t size>
operator bool(std::bitset<size> & b)
{
return b.any();
}
but I got
error C2801: 'mynamespace::operator bool' must be a non-static member
from my visual-studio.
But when I look up C2801 explanation it says nothing about conversion operators (only about =, ->, [],())
So, is it possible to somehow write "Conversion std::bitset to bool operator?"
(I can not call b.any() in my if-statements, because the same code must run when std::bitset is replaced with unsigned or something
typedef std::bitset<x> Bitset;
//typedef unsigned Bitset;
so the ideal syntax will be like:
Bitset b = whatewer;
if(b)
doStuff();
)
If this overloading is not possible, what is the recommended workaround?
so far I use it like:
if(b == Bitset(0))
doStuff();
but I dont like it.
Thank you
As the error message says, the conversion operator must be a non-static member of a class. That is true.
I can not call b.any() in my if-statements, because the same code must run when std::bitset is replaced with unsigned or something.
If that is your problem, then you can use function overload, and call it passing the argument which will return a boolean value:
template<typename T>
bool to_bool(T const & b)
{
return b; //implicit conversion (if allowed) for all other types
}
template<size_t N>
bool to_bool(std::bitset<N> const & b)
{
return b.any();
}
then use it as:
if (to_bool(whatever))
{
}
It will call the correct overload. If the type of whatever is std::bitset<N> then the second overloaded function will be called, or else the first one will be called.
§12.3.2/1: "A member function of a class X with a name of the form [...] specifies a conversion from X to the type specified..." (C++11 uses the same section number and nearly the same wording, adding only that the function takes no parameters).
The other possible way to define a conversion is a constructor (§12.3.1), which is obviously a class member as well.
In short, yes, conversions must always be defined as member functions.
One way to do what you want would be to write a wrapper around std::bitset that provides the conversion you care about:
template <int size>
class mybitest {
std::bitset<size> bits;
public:
operator bool() { return bits.any(); }
}
But if you decide to do that, you'll need to write forwarding functions for essentially all the pieces of bitset you're using (ctors, assignment, etc.)
The standard is a bit unclear on this (12.3.2):
A member function of a class X having no parameters with a name of the form [...] specifies a conversion from X to the type specified by the conversion-type-id. Such functions are called conversion functions. No return type can be specified. If a conversion function is a member function, the type of the conversion function (8.3.5) is “function taking no parameter returning conversion-type-id”.
The first sentence seems to imply that only member functions can be conversion functions, but I'm not sure what the purpose of the conditional "if a conversion function is a member function" is.
I'd take the first sentence as binding and conclude that a conversion function must be a member function.
in case this helps somebody, you can actually provide a not operator instead
template<size_t size>
operator !(std::bitset<size> & b)
{
return !b.any();
}
and use it like so using the !! idiom:
if (!!whatever)
{
}
still not ideal, but a bit closer I think.
Let say I have a object. I'm assigning that to an integer.
MyClass obj1 = 100;//Not valid
Let's say, I have a parameterized constructor which accepts an integer.
MyClass(int Num)
{
// .. do whatever..
}
MyClass obj1 = 100;//Now, its valid
Likewise on any circumstance, does the vice-versa becomes valid?!.
eg) int Number = obj1;//Is it VALID or can be made valid by some tweeks
EDIT:
I found this to be possible using Conversion Functions.
Conversion functions are often called "cast operators" because they (along with constructors) are the functions called when a cast is used.
Conversion functions use the following syntax:
operator conversion-type-name ()
eg) Many have explained it neatly below
Yes, provided that the object is implicitly convertible to an int, either directly or through an intermediate object.
E.g. If your class have a conversion operator int it would work:
MyClass
{
public:
operator int() const { return 200; }
};
C++ constructors that have just one parameter automatically perform implicit type conversion. This is why conversion from int to MyClass works. To create conversion from MyClass to int you have to define operator int() inside MyClass.
Yes you can, using user defined conversions.
In your MyClass, define operator int()
So
class MyClass
{
int myVal;
public:
operator int() { return myVal;}
}
Yes, you need to add a conversion operator to MyClass
operator int();
MyClass is not an integer therefore you can't do int Number = obj1;
You should have a method or operator(stated by others) in MyClass that returns an int. (int number = obj1.GetNum();)