Converting to an explicit type in C ++

I am trying to write a class that implements 64-bit ints for a compiler that does not support long long , which will be used in existing code. Basically, I should have somewhere a typedef that selects whether I want to use long long or my class, and everything else should compile and work.

So, I obviously need conversion constructors from int , long , etc. and corresponding conversion operators (castings) to these types. This seems to be causing errors with arithmetic operators. Using native types, the compiler “knows” that when calling operator*(int, char) it must advance char to int and call operator*(int, int) (instead of, for example, casting int to char )). In my case, this is confused between the various built-in operators and the ones I created.

It seems to me that if I can somehow declare the conversion operators explicit, this will solve the problem, but as far as I can tell, the explicit keyword is only for constructors (and I cannot make constructors for built-in types).

So, is there a way to mark the cast as explicit? Or am I barking the wrong tree here and there, another way to solve this? Or maybe I'm just doing something else wrong ...

EDIT:

A little clarification as to what I want to do: I have a project that uses 64-bit (long long) operations in many places, and I'm trying to port it to the platform, in support of 64-bit variables / operations. Despite the fact that I have a source for the project, I would prefer not to go through thousands of places where the built-in operators and casts in the style of C and change them.

As for the code itself, the project has the following definitions and types of code:

 typedef long long i64; // I would like to only have to change this to use my class instead of "long long" int a; unsigned b; int c = ((i64)a*b)>>32; 

Regarding the implementation of the class, I have the following:

 class Long64 { public: Long64(); Long64(const Long64&); Long64(int); Long64(long); Long64(unsigned int); Long64(unsigned long); operator int() const; operator long() const; operator unsigned int() const; operator unsigned long() const; friend Long64 operator*(int l, const Long64& r); friend Long64 operator*(const Long64& l, int r); friend Long64 operator*(long l, const Long64& r); friend Long64 operator*(const Long64& l, long r); } 
+4
source share
2 answers

To avoid compiler confusion, you will help it by specifying a combination of its class and built-in types for the entire arithmetic operator. For example, for the + operator, you need to define + unsigned

 MyClass operator+(char, MyClass const&); MyClass operator+(MyClass const&, char); MyClass operator+(short, MyClass const&); MyClass operator+(MyClass const&,short); MyClass operator+(MyClass const&,int); 

the compiler will prefer overloads that conversion operators should not use.

Of course, all these methods will use overloading. MyClass + operator (MyClass const &, MyClass const &);

by explicitly converting one of the parameters to your MyClass class

 MyClass operator+(char c, MyClass const& m) { return MyClass(c)+m;} 

It's a little cumbersome, I know, but he has to avoid conflicts.

+3
source

You should create methods with meaningful names instead of conversion operators - for example, toLongLong() instead of operator long long() - this way you can write code that is easy to understand for both people and the compiler. This is the only sensible solution when you have so many conversion statements that even the compiler cannot get what you want.

+2
source

Source: https://habr.com/ru/post/1308108/


All Articles