Best Practices for Trailing Return Types
What are some best practices to follow when using trailing return types in C++?
Here are some practices to consider when deciding whether to use trailing return types.
Use them when they're necessary
Trailing return types are most useful in template functions where the return type depends on the template parameters. If you don't need them, it's often simpler to stick to traditional return type syntax.
Keep them readable
Just because you can use trailing return types doesn't mean you should use overly complex expressions. If the return type is getting too complicated, consider simplifying your function or using a type alias.
// This is hard to read:
auto ComputeValue(int x, int y)
-> decltype((x * y) / (x + y)) {
return (x * y) / (x + y);
}
// This is better:
using ResultType = decltype((x * y) / (x + y));
auto ComputeValue(int x, int y) -> ResultType {
return (x * y) / (x + y);
}Be consistent
If you're working on a team or codebase, agree on a consistent style. Either use trailing return types everywhere, or only use them when necessary. Mixing styles can lead to confusion.
Remember the const position
If you're using trailing return types with const member functions, remember that the const goes before the return type, not after.
// Wrong:
auto GetValue() -> int const;
// Right:
auto GetValue() const -> int;Use clear and descriptive names
This is a general principle, but it's especially important with trailing return types. Since the return type comes after the function name, the name should clearly indicate what the function does and what it returns.
// Unclear:
auto Func(int x, int y) -> int;
// Better:
auto ComputeAverage(int x, int y) -> double;Trailing Return Types
An alternative syntax for defining function templates, which allows the return type to be based on their parameter types