zhihuifan
zhihuifan

Reputation: 1113

strange c++ operator (operator unsigned short())

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?

Upvotes: 1

Views: 4213

Answers (4)

Hu Xixi
Hu Xixi

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

paxdiablo
paxdiablo

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

R Sahu
R Sahu

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

Yu Hao
Yu Hao

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

Related Questions