views:

157

answers:

3

I have a constructor of the form:

MyClass(int a, int b, int c);

and it gets called with code like this:

MyClass my_object(4.0, 3.14, 0.002);

I would like to prevent this automatic conversion from double to int, or at least get warnings at compile time.

It seems that the "explicit" keyword does not work in these case, right?

+2  A: 

Declare a private MyClass(double a, double b, double c) constructor.

Kristopher Johnson
+7  A: 

What's your compiler? Under gcc, you can use -Wconversion to warn you about these types of conversions.

Martin B
I use gcc, and the -Wconversion did work!I thought the -Wall would include this, but apparently it doesn't!Thanks a lot!
Hugo
-Wall lacks a lot of things and not even -Wall -Wextra includes everything. I would prefer having a switch to really enable all warnings and then disable the ones that are causing trouble one-by-one.
Tronic
+5  A: 

Declare a private constructor like this:

private:
template <class P1, class P2, class P3>
MyClass(P1,P2,P3);

That will cause a compile time error for any construction using 3 parameters that aren't all int, and it's portable.

Joe Gauterin
That's clever. :-) The warning solution is a bit cleaner, but your solution works on any conforming compiler. :-) Unfortunately it does not protect against the class constructing instances of itself directly. You have to wait until link time to catch those.
Omnifarious
@Omnifarious: With C++0x you'd simply mark this overload with `= delete;` Otherwise, if you were worried about internal misuse, you could provide an implementation that fails to compile (e.g because of static assertion).
visitor
Cleverer: add a second overload `template <class P1, class P2, class P3> MyClass(P1,P2,P3, P3* dummy = 0);`. Overload resolution between the two templates will be ambiguous, but this is irrelevant if both are worse than `MyClass(int,int,int)`
MSalters
@visitor: I believe `= delete;` can only be used to remove functions that would otherwise be automatically declared and defined by the compiler.
Omnifarious
@Omnifarious: It seems eliminating unwanted conversions is one intended usage of `= delete`. See the C++0x FAQ: http://www2.research.att.com/~bs/C++0xFAQ.html#default
visitor
@visitor: How interesting. Reading the rationale behind their choice in http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2326.html makes their choice seem very sensible. It was intended for exactly this sort of situation. Thanks!
Omnifarious