[comp.lang.c++] Implicit argument coercion consider

spalding@uiucdcsp.cs.uiuc.edu (01/05/88)

I think the best way to control type conversion of arguments is
to make the arguments class objects instead of simple types.  Then
you can control how the arguments are converted.  Each argument can
be controlled individually, so you avoid the problem of excessive
numbers of overloaded functions.  In the color example, define
a class color with constructors for each type you want to allow:

#include <stream.h>
class color {
public:
	float intensity;
	color(float i) {intensity = i;}
	color(int i) {intensity = i / 255.0;}
};

void show(color red, color green, color blue)
{
	cout <<     "red: " <<   red.intensity
	     << ", green: " << green.intensity
	     <<  ", blue: " <<  blue.intensity << "\n";
}

main()
{
	show(0.5, 0.25, 255);
	show(127, 1.0, 0);
}

This program produces the following output:

red: 0.5, green: 0.25, blue: 1
red: 0.498039, green: 1, blue: 0

If you don't want to allow the integer arguments,
just remove the second constructor and the compiler
produces the following error messages:

CC  colors.c:
"colors.c", line 18: error: cannot make a color from a int 
"colors.c", line 19: error: cannot make a color from a int 
2 errors

The second problem of forcing programmers to use macros you've
set up for particular parameters can also be solved with classes.
In this case, the constructor has a second (unused) argument so
that C++ will not allow any automatic conversion.  In the following
example, the procedure "routine" must be called with the argument
BIG or SMALL, but TRUE, FALSE, 0, etc., are not allowed:

class opt1 {
public:
	int value;
	opt1(int m, int) {value = m;}
};

const opt1 BIG(0, 0);
const opt1 SMALL(1, 0);

const int FALSE = 0;
const int TRUE = 1;

extern void routine(opt1);

main()
{
	routine(BIG);
	routine(SMALL);
	routine(TRUE);
	routine(0);
}

The last two calls to routine generate the following error messages:

CC  options.c:
"options.c", line 19: error: cannot make a opt1 from a const int 
"options.c", line 20: error: cannot make a opt1 from a zero 
2 errors