When a function has several consecutive parameters of the same type, there is a risk that the arguments are not provided in the right order.
Moreover, it is generally the sign of code which is too low-level. Maybe
- the arguments should have a stronger type
- some arguments could be grouped together to form a higher level abstraction.
The use of two parameters of the same type is useful in situations like comparing arguments, combining arguments through a binary operation and
swapping arguments but three or more arguments of the same type is considered bad practice.
This rule raises an issue when a function is defined with more than two consecutive parameters of the same type. For this rule, only the "raw" type
of the parameter will be considered (a string const &
will be considered the same type as a std::string
).
Noncompliant code example
double acceleration(double initialSpeed, double finalSpeed, double deltaT) { // Noncompliant
return (finalSpeed - initialSpeed) / deltaT;
}
double dot_product(double x1, double y1, double x2, double y2); // Noncompliant
void f() {
double x1,x2,y1,y2;
auto result = dot_product(x1,x2,y1,y2);// The order is wrong, even if it might look logical
auto acc = acceleration(10, 50, 110); // Very unclear, probably a bug...
}
Compliant solution
// This code assumes the use of a strong type / units library
Acceleration acceleration(Speed initialSpeed, Speed finalSpeed, Duration deltaT){
return (finalSpeed - initialSpeed) / deltaT;
}
struct point {
double x;
double y;
};
double dot_product(point p1, point p2);
double f() {
point p1,p2;
auto result = dot_product(p1,p2);
auto acc = acceleration(50 * km / hour, 110 * km / hour, 10s);
}