#include <iostream>
#include <cmath>
using namespace std;
class Complex
{
private:
double real;
double imag;
public:
// Default constructor
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i)
{}
// magnitude : usual function style
double mag()
{
return getMag();
}
// magnitude : conversion operator
operator int ()
{
return getMag();
}
private:
// class helper to get magnitude
double getMag()
{
return sqrt(real * real + imag * imag);
}
};
int main()
{
// a Complex object
Complex com(3.0, 4.0);
// print magnitude
cout << com.mag() << endl;
// same can be done like this
cout << com << endl;
}
I don't understand how the compiler is resolving to call the conversion operator for cout << com << endl;.
I can also have more than one conversion operator in the same class. How will the resolution be done in that case?
You have declared a conversion operator to int. Since this operator is not explicit, the compiler considers it when finding the best overload of ostream::operator<<. Keep in mind that C++ compiler always attempts to automatically convert types to find a matching call, including conversion constructors, conversion operators and implicit type conversions.
If you do not want this behavior, then starting from C++11 you can mark the operator as explicit:
explicit operator int() {
return getMag();
}
Regarding the second part of your question, if there are multiple conversions that are equally good, a compile error is invoked. If you added, say, operator double, then as there exists ostream::operator(double), the call would be ambiguous and you would need to cast com to Your desired type.
I supose that the compiler tries to convert to a type for which cout has an overload defined.
If it can be converted to 2 types for which cout has an overload defined you will get a compilation error.
If you add this function to the class code won't compile:
// magnitude : conversion operator
operator float ()
{
return getMag() + 1;
}
To solve that you must do a cast like that:
// same can be done like this
cout << "Com: " << (float) com << endl;
Related
class B{
float floatVar;
public:
B(float a):floatVar(0.0){
floatVar = a;
}
operator int(){ // Consider this as line A
return floatVar;
}
};
int main()
{
B floatObj(5.5);
cout << floatObj; // Consider this as line B
return 0;
}
when i cout while overloading int() it displays 5 and when i replace int() with float() in line A , program displays 5.5.
I want to know how it is automatically calling the int() typecaster or the float() in cout?
There is no synthesis of default printing function or alike in C++, thus defining a class with some fields doesn't print them by default if you try to print an objet of the class.
As you didn't defined any overloaded operator << to print to some ostream (like cout) the compiler found a way to print it through the defined conversion to int.
Compiler is allowed to perform one user-defined conversion implicitly when searching for matching function overload. Since you provide conversion from B to int, compiler can use that and select operator <<(std::ostream, int) overload of the << operator for std::cout.
If you would add another conversion to a type that is accepted by operator << for std::ostream (e.g. float), compiler would say that it is ambiguous call and it cannot choose by itself.
class B{
float floatVar;
public:
B(float a):floatVar(0.0){
floatVar = a;
}
operator int(){
return floatVar;
}
operator float(){
return floatVar;
}
};
int main()
{
B floatObj(5.5);
cout << floatObj; //error: ambiguous overload for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'B')
cout << static_cast<int>(floatObj); //explicit conversion, compiles
return 0;
}
I wrote implicit cast operator to double and explicit cast operator to int in foo class, and function that takes int as an argument. Despite of being called with not casted foo object code gets executed.
I used gcc PRETTY_FUNCTION and found out that foo object gets casted to double then to int.
class foo
{
public:
int x, y;
foo(int x, int y) : x{x}, y{y} {}
explicit operator int() {cout << __PRETTY_FUNCTION__ << "\n"; return x/y;}
operator double() {cout << __PRETTY_FUNCTION__ << "\n"; return double(x)/double(y);}
};
void printint(int x)
{
cout << x << "\n";
}
int main()
{
foo var(1,2);
printint(var);
}
I expected this not to compile because of explicit operator, but instead it does and prints 0 as int(1/2).
Output of program is:
foo::operator double()
0
From cppreference:
Implicit conversion sequence consists of the following, in this order:
1) zero or one standard conversion sequence;
2) zero or one user-defined conversion;
3) zero or one standard conversion sequence.
Hence your foo can be converted to a double (2) and then the double is converted to an int (3).
If you want the code to not compile you have to also make the double conversion explicit. The explicit only prevents your foo to convert to a int in step 2 alone, but in the whole sequence the conversion can still be done implicitly. Implicit conversion can be tricky and becaue of (1) and (3) a single user provided implicit conversion (2) can have unexpected side effects.
of course it will use the double conversion operator and then cast the double to a int. the double conversion operator can implicitly be called. Remove explicit and it won't cast to double first
It can't use the explicit operator int() because of the explicit
'int' and 'double' conversion functions is 'explicit' and in this code why have I permit for use this conversion instead of error message?
If I delete all my conversion overload functions code occur 'conversion error'
class Person
{
public:
Person(string s = "", int age = 0) :Name(s), Age(age) {}
operator string() const { return Name; }
explicit operator int() const{ return 10; } // ! Explicit
explicit operator double()const { return 20; } //! Explicit
operator bool()const { if (Name != "") return true; return false; } // using this
};
int main(){
Person a;
int z = a;
std::cout << z << std::endl; // Why print "1"? Why uses bool conversion?
}
I this it is answer:
Because 'a' can not be convert to int or double it occur error, but because it has bool conversion function, which can convert to int and int to double, code use this function.
int z = a;
Looks innocuous, right?
Well, the above line calls the implicit bool-conversion-operator, because that's the only way you left it to get from Person to int, and that only needs one user-defined conversion (the maximum allowed).
This is the reason for the safe-bool-idiom before C++11, and the major reason for the general advice to mark conversion operators and single-argument ctors explicit unless they are not transformative nor lossy.
If you want to see it for yourself, fix your code and trace invocation of your operator bool.
I run into a strange c++ operator.
http://www.terralib.org/html/v410/classoracle_1_1occi_1_1_number.html#a0f2780081f0097af7530fe57a100b00d
class Number {
..
operator unsigned short () const;
};
I called this operator as:
a Number(..);
unsigned short b = a.operator unsigned short();
this works, but I can't understand how it works.
first, this operator don't have a return value.
seconds, a.operator unsigned short() is really strange to me. What is a better way to call this?
if I call :
unsigned short b = a; does the operator will get called? is there any c++ standard to say about this?
The function is a user defined conversion operator. More details can be found at http://en.cppreference.com/w/cpp/language/cast_operator.
You said,
this operator don't have a return value. seconds,
The return values of the user define conversion operators is the explicit type. In your case, the return type is unsigned short.
You asked:
What is a better way to call this?
You could do an explicit cast to invoke the function.
Number n;
unsigned short s = (unsigned short)v;
It is also called when an conversion is required by the compiler.
void foo(unsigned short s) {}
Number n;
foo(n); // Number::operator unsigned short() is called to cast
// n to an unsigned short.
You asked:
if I call : unsigned short b = a; does the operator will get called? is there any c++ standard to say about this?
Yes. The user defined operator function gets called.
Here's the relevant sections from the C++ Draft Standard (N3337):
12.3.2 Conversion functions
1 A member function of a class X having no parameters with a name of the form
...
[ Example:
struct X {
operator int();
};
void f(X a) {
int i = int(a);
i = (int)a;
i = a;
}
In all three cases the value assigned will be converted by X::operator int(). — end example ]
This is the conversion operator. A conversion function typically has the general form
operator type() const;
where type represents a type. It means objects of type Number can be converted to short int.
The conversion operator have no explicitly stated return type and no parameters, because the return type is exactly the type in the signature.
It's a conversion function, called to convert your type into a specific other type under various conditions, and it's covered in ISO C++11 12.3.2 Conversion functions.
In your case, it's called when the Number instance needs to be converted into an unsigned short.
By providing conversion operators, you can take full control over what happens during the conversion process, including such evil as the following:
#include <iostream>
struct X {
int val;
X(int v) { val = v; };
operator int() { return val + 1; }; // pure evil
friend std::ostream& operator<< (std::ostream&, X&);
};
std::ostream& operator<< (std::ostream &out, X &x) {
out << x.val;
return out;
}
int main (void) {
X xyzzy (42);;
std::cout << xyzzy << '\n';
std::cout << (int)xyzzy << '\n';
return 0;
}
which will output the value when you use the instance directly, but output something totally different when you cast it.
Now granted, that's rather evil and not a really good use case but you can use this for things such as rounding floats rather than truncating them, when converting to an integer:
#include <iostream>
struct X {
double val;
X(double v) { val = v; };
operator int() { return (int)(val + 0.5); };
friend std::ostream& operator<< (std::ostream&, X&);
};
std::ostream& operator<< (std::ostream &out, X &x) {
out << x.val;
return out;
}
#define E 2.718281828456
int main (void) {
X xyzzy (E);
double plugh = E;
std::cout << plugh << " -> " << (int)plugh << '\n';
std::cout << xyzzy << " -> " << (int)xyzzy << '\n';
return 0;
}
The output of that code is:
2.71828 -> 2
2.71828 -> 3
As a supplement for the first answer, when you use keyword explicit, note the difference, using explicit would force the programmer to assert his intention to convert using a cast:
class Number {
private:
int num;
public:
explicit Number(int number) : num(number) {} // constructor
explicit operator unsigned short () const { // conversion operator
return num;
}
};
int main() {
Number classTypeNumber(10);
// unsigned short convertToUshortNumber = classTypeNumber; // error
// implicit conversion is not allowed.
// now you should explicit convert the instance first.
// typedef unsigned short int __u_short in types.h file.
unsigned short convertToUshortNumber = static_cast<__u_short>(classTypeNumber);
cout << convertToUshortNumber;
}
I'm trying to overload the + operator in C++, but get the following error:
operators.cpp: In function ‘int main()’:
operators.cpp: 23:17: error: cannot convert ‘Operators’ to ‘int’ in initialization
This is my code:
#include <iostream>
using namespace std;
class Operators{
private:
int num1;
public:
Operators(int num1){
this->num1 = num1;
}
Operators operator+(Operators o){
return Operators(num1 + o.num1);
}
};
int main(){
Operators o1(5);
Operators o2(10);
Operators res = o1 + o2; // EDITED
cout << res;
}
Could you please help me?
I know, in this case it doesn't make sense to overload it, as I could just say 5+10, but I'm just experimenting.
UPDATE
Thanks, I've edited the int.
But now I'm getting the following error:
operators.cpp: In function ‘int main()’:
operators.cpp: 25:10: error: match for ‘operator<<’ in ‘std::cout << res’
[...]
The problem with this line:
int res = o1 + o2;
Is that your overload of operator + returns an object of type Operators. This means that you are trying to initialize an int (res) from a temporary of type Operators (the result of o1 + o2), but there is no user-defined conversion for doing that.
This is why the compiler is issuing an error. You can fix this easily by adding a conversion operator to your Operators class:
operator int () const { return num1; }
UPDATE:
It seems you have updated your question. The second line below is problematic:
Operators res = o1 + o2;
cout << res;
Unless you defined an overload of operator << for your Operators class, the compiler won't know which overload of operator << to pick for streaming your object of type Operators.
To solve the issue, you can:
Define a conversion operator to int, as suggested above
Define an overload of operator << for Operators, as follows:
friend std::ostream& operator << (std::ostream& o, Operators const& op)
{
o << op.num1;
return o;
}
Here is a live example.
As the error message is trying to tell you, o1 + o2 is of type Operators.
You can't assign that to an int
Your operator+ returns an Operators object. You then try and assign this result to int res. YOu have given no way to convert from an Operators object to an int. You could provide a conversion operator to do this:
operator int() {
return num1;
}
This defines a conversion from Operators to int.
You need to write:
int res = o1.getMethod() + o2.getMethod();
where getMethod() is a public method in your class that returns the private integer num1.
Otherwise, you don't have access to it. Try it.
Change int to Operators, and implement your own copy and default constructor.
#include <iostream>
class Operators
{
private:
int num1;
public:
Operators() = default;
Operators(Operators const& op) : num1(op.num1) {}
Operators(int num1)
{
this->num1 = num1;
}
Operators operator+(Operators o)
{
return num1 + o.num1;
}
};
int main()
{
Operators o1(5);
Operators o2(10), res;
res = o1 + o2;
std::cout << res;
}
To make this work further, create an overload of operator<< and print the sum.