Reputation: 1113
I run into a strange c++ operator.
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?
Upvotes: 1
Views: 4213
Reputation: 2157
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;
}
Upvotes: 0
Reputation: 882028
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
Upvotes: 0
Reputation: 206667
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 ]
Upvotes: 6
Reputation: 122443
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.
Upvotes: 1