Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloading c++ typecasting (functions)

Using C++ style typecastings (all 4) look exactly like some function template. e.g.

template<typename TO, typename FROM>
TO dynamic_cast (FROM p);

will be used as,

dynamic_cast<Derived*>(p); // p is Base*

Why is it not allowed to overload them by language standard for custom usage ? (like we can overload the keywords like new/delete or other operators)

like image 791
iammilind Avatar asked May 12 '11 07:05

iammilind


1 Answers

You cannot overload these operators. It is, arguably, because you cannot change the meaning of such a fundamental thing as other answers say. (Like changing the meaning for + for integers, or the * decoration to generate a pointer from a type).

Having said that, nothing prevents you from defining your own generalizations of cast functions, that take an argument and return things very related to it. Actually, I would argue the opposite point of view, you should never use the language cast operations (static/dynamic/reinterpret_cast) unless you are doing pretty low level stuff.

What you would want to do probably is to define your own casting function that most of the time behaves like the ones provided by the language but once in a while they do something more specific for your specific purposes. You have to think hard what this function really does and name it well. What kind of runtime cost you can afford, what kind of behavior on "failure" (throw execption?, return a null value?), etc.

The standard and many libraries are full of such functions. Sometimes they add a tweaked behavior over language cast, other times they do more. Some examples:

https://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast

  • std::static_pointer_cast,
  • std::dynamic_pointer_cast,
  • std::const_pointer_cast,
  • std::reinterpret_pointer_cast

  • std::any_cast

  • std::chrono::time_point_cast

(see also https://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/pointer_cast.html)

https://www.boost.org/doc/libs/1_42_0/libs/conversion/lexical_cast.htm

  • boost::lexical_cast

https://www.boost.org/doc/libs/1_63_0/libs/conversion/cast.htm

  • polymorphic_cast,
  • polymorphic_downcast,
  • polymorphic_pointer_cast
  • polymorphic_pointer_downcast

https://www.boost.org/doc/libs/1_72_0/libs/numeric/conversion/doc/html/boost_numericconversion/improved_numeric_cast__.html

  • boost::numeric_cast

https://www.boost.org/doc/libs/1_47_0/doc/html/boost_units/Quantities.html#boost_units.Quantities.Quantity_Construction_and_Conversion

  • boost::units::quanity_cast.

Sometimes they are not called cast at all :)

https://en.cppreference.com/w/cpp/utility/variant/get_if

  • std::get_if

Another example, for template code I wrote this cast function that is only invoked if the conversion can be done implicitly:

    template<class To, class From, std::enable_if_t<std::is_convertible<From, To>{}, int> =0>
    To implicit_cast(From&& f){
        return static_cast<To>(f);
    }

https://godbolt.org/z/ym8MnJ

like image 192
alfC Avatar answered Oct 01 '22 00:10

alfC