It's quite common to end up writing methods that take booleans to say whether certain functionality should be switched on or off. It would be nicer to use enumerations, not least because that way you couldn't end up getting them the wrong way around.
Something like:
void DoSomething(Thing thing, bool withLogging, bool withRollBack){}which would
(
Read more... )
DoSomething(thing, logging:True, rollback:False)
That's one of the things in C# which I wish C++ would hurry up and have properly.
Of course, anywhere where you do want more than two options, your enum syntax would be useful. Especially if, for the rare cases where you need it, you could use that as a variable type. And if there was a syntax that prevented the enum polluting any namespaces outside the function.
Reply
Reply
Reply
Named parameters are a big plus for me but I guess some people see it as incompatible with the style of their language. In C++ in fact I think there's no requirement that the names in a prototype and an implementation be the same so
class MyObject {
void wibble(int thisInt, int thatInt).
}
can by implemented as
MyObject::wibble(int thatInt, int thisInt);
And I imagine requiring parameter names be consistent in prototype and impl would break code? So I imagine there's scope for a lot of confusion.
Reply
Oh yes, I'd forgotten that. I'm not sure it's a good thing, but it's how it's always been.
But IIRC whenever you call a function, you're calling a particular prototype which is then linked to the implementation at link time. For instance, I think the default parameters are specified in the prototype not implementation and could in principle be different in two different prototypes although that would be horrible. So I assumed this would work the same way -- the compiler would match the parameter names where you call it to the prototype, turn it back into a call to a function name based on positional parameters, and then the linker would link that with the implementation ignoring the names of the parameters?
Reply
class MyObject{
void myMethod( int myThis=1, int myThat=2);
}
MyObject::MyMethod (int myThat=3, int myThis=4)
{
// Hooray for ambiguity
}
C++ really does allow you to confuse yourself in multiple ways. Actually I don't think the named parameters make things terribly worse here.
The bad thing is that, in fact, sometimes prototype argument names do get out of step with the implementation due to careless refactoring.
Reply
I don't think it's _quite_ that bad. I think the compiler gives an error or at least a warning (?) if you specify contradictory defaults in the declaration and implementation, or two different declarations seen by the same file. I agree it's not very reliable, but I think to actually screw it up you need two different header files and only ever include one of them, or to have a contradictory header file and implementation file, and not include the header in the implementation...
Reply
class MyObj {
void myMethod(int thisVar=1, int thatVar=2);
};
void MyObj::myMethod(int thatVar, int thisVar)
{
}
Reply
Reply
Inline enum definitions would suffer from the same problem, but perhaps - hopefully! - to a lesser extent. Personally I'd still rather have the enum properly and separately defined and documented (with XML comments), but I'm at the picky end of the scale on stuff like that.
Even when there are only two options, an enum's generally better than a Boolean because if an unforeseen third option comes up, adding it is not necessarily a breaking change.
Reply
If I had a method like this with three (or more) parameters which weren't in a perfectly obvious order, I'd say "this method call is too complex for positional parameters, it wants named arguments". And if that didn't happen, it would fail code review. That's how you enforce that sort of thing.
This also lets you provide useful defaults, so if e.g. you expected to log things, but didn't normally need a rollback, you'd just say doSomething(thing => thingObject) and that would be that.
Reply
But yes, definitely allows it.
Reply
Leave a comment