4

How can we tell the C++ compiler that it should avoid implicit casting while using arithmetic operators such as +and /, i.e.,

size_t st_1, st_2;
int    i_1,  i_2;

auto st = st_1 + st_2; // should compile
auto i  = i_1  + i_2;  // should compile

auto error_1 = st_1 + i_2;  // should not compile
auto error_2 = i_1  + st_2; // should not compile
// ...
abraham_hilbert
  • 2,221
  • 1
  • 13
  • 30

3 Answers3

5

Unfortunately the language specifies what should happen when you add an int to a size_t (see its rules for type promotion) so you can't force a compile time error.

But you could build your own add function to force the arguments to be the same type:

template <class Y>
Y add(const Y& arg1, const Y& arg2)
{
    return arg1 + arg2;
}

The constant references prevent any type conversion, and the template forces both arguments to be the same type.

This will always work in your particular case since size_t must be an unsigned type:

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

With built in (non-class) types, it is not possible to prevent unwanted implicit type conversions.

Some compilers can be configured to give warnings for operations involving suspicious conversions, but that does not cover all possible implicit conversions (after all, a conversion from short to long is value preserving, so not all compilers will report it as suspicious). And some of those compiles may also be configured to give errors where they give warnings.

With C++ class types, it is possible to prevent implicit conversions by making constructors explicit, and not defining conversion operators (for example, a class member function named operator int()).

It is also possible for a class type to supply numeric operators (operator+(), etc), which only accept operands of the required types. The problem is that this doesn't necessarily prevent promotion of built in types participating in such expressions. For example, a class that provides an operator+(int) const (so some_object = some_other_object + some_int would work) would not stop an expression like some_other_object + some_short from compiling (as some_short can be implicitly promoted to int).

Which basically means it is possible to prevent implicit conversions to class types, but not prevent promotions occurring in expressions with numeric operators.

Peter
  • 35,646
  • 4
  • 32
  • 74
1

The best answer I can give you is to use units: give a look at boost unit.

Another interesting method is the use of opaque typedef you can give a look at this paper Toward Opaque Typedef here a very interesting talk and implementation.

Hope the material can be useful

Elvis Dukaj
  • 7,142
  • 12
  • 43
  • 85