CppCoreGuidelines icon indicating copy to clipboard operation
CppCoreGuidelines copied to clipboard

T.100 Suggested Example

Open eisenwave opened this issue 2 years ago • 3 comments

template<typename... T>
void print_all(const T& ...args) {
    (output(args), ...);
}

print_all(a, 0, string{"xyz"}); // good, type-safe

printf("%d %d %s", a, 0, "xyz"); // bad, UB if %d the wrong specifier for a,
                                 // UB if we use std::string

I think this example demonstrates nicely how variadic functions are a "just works" solution and what safety issues arise with printf by comparison.

eisenwave avatar Jun 23 '23 18:06 eisenwave

could even make it complete with (std::cout << ... << args); except it doesn't space-separate..

cubbimew avatar Jun 24 '23 03:06 cubbimew

((std::cout << args << ' '), ...);

would be closer, but this isn't so nice-looking. If you wanted to avoid a trailing space, it would get even worse, because you would need a conditional operator and an index outside the fold expression:

size_t i = 0;
((std::cout << args << (i == 0 ? "" : " ")), ...);

That's why I think it's for the best to keep it at an abstract output function.

eisenwave avatar Jun 24 '23 06:06 eisenwave

Printf has its purpose with embedding output formatting in meaning and easy mechanisms.

This may work as a replacement for variadic arguments for some cases, but printf is not one of them.

BenjamenMeyer avatar Jun 26 '23 15:06 BenjamenMeyer