Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

are casts overridable operations? if so, how?

Is it possible to override (C-style) casts in C++?

Suppose I have the code

double x = 42;
int k = (int)x;

Can I make the cast in the second line execute some code I wrote? Something like

// I don't know C++
// I have no idea if this has more syntax errors than words
operator (int)(double) {
    std::cout << "casting from double to int" << std::endl;
}

The reason I ask is because of the question "Is there any way to get gcc or clang to warn on explicit casts?" and my suggestion there.

like image 578
pmg Avatar asked Dec 13 '22 03:12

pmg


2 Answers

§ 12.3.1/1 "Type conversions of class objects can be specified by constructors and by conversion functions. These conversions are called user-defined conversions and are used for implicit type conversions (Clause 4), for initialization (8.5), and for explicit type conversions (5.4, 5.2.9)."

Yes, we can make conversions, but only if one or both sides is a user-defined type, so we can't make one for double to int.

struct demostruct {
    demostruct(int x) :data(x) {} //used for conversions from int to demostruct
    operator int() {return data;} //used for conversions from demostruct to int
    int data;
};

int main(int argc, char** argv) {
    demostruct ds = argc; //conversion from int to demostruct
    return ds; //conversion from demostruct to int
}

As Robᵩ pointed out, you can add the explicit keyword to either of those conversion functions, which requires the user to explicitly cast them with a (demostruct)argc or (int)ds like in your code, instead of having them implicitly convert. If you convert to and from the same type, it's usually best to have one or both as explicit, otherwise you might get compilation errors.

like image 146
Mooing Duck Avatar answered Dec 31 '22 23:12

Mooing Duck


Yes, but only for your own types. Look at this:

#include <iostream>
struct D {
  // "explicit" keyword requires C++11
  explicit operator int() { std::cout << __FUNCTION__ << "\n"; }
};

int main () {
  int i;
  D d;
  //i = d;
  i = (int)d;
}

So, you cannot create double::operator int(), but you could create MyDouble::operator int().

like image 26
Robᵩ Avatar answered Dec 31 '22 23:12

Robᵩ