While trying to figure out the optimal ordering for optional parameters to a function recently, I stumbled across this blog post and accompanying GitHub repo, which provides a header for a Pythonic kwargs
-like facility in C++. Though I didn't end up using it, I find myself wondering whether this is a good or not in a strongly-typed language. Having worked in Python for a while, I find the notion of a kwargs
-like facility in my project very appealing because many of its objects/functions have a number of optional parameters (which cannot be avoided, unfortunately), yielding long lists of constructors that differ by one or two parameters and could be made much more succinct/DRY-ish.
What, if anything, is others' experience with stuff like this? Should it be avoided? Are there guidelines for it? What are the potential problems/pitfalls?
Best Answer
I'm not very much familiar with C++ kwargs but a couple of disadvantages come to mind after skimming their source:
They require globally pre-declaring all arguments. The simple example on the blog post has this section which is dead weight:
Not as concise as the pythonic original.
C++ offers native alternatives to achieve the functionality of named parameters:
Struct wrappers. Define your optional parameters as fields of a struct.
Proxy objects. Arguments are stored in a temporary struct which can be modified with chained setters.
Note: the boilerplate can be abstracted out to a macro at the expense of readability:
Variadic functions. This obviously is type-unsafe and requires knowledge of type promotions to get right. It is, however, available in pure C if C++ is not an option.
Note: In C++ this can be made type-safe with variadic templates. The run-time overhead will be gone at the expense of slower compilation times and binary bloat.
boost::parameter. Still a third-party library, albeit more established lib than some obscure github repo. Drawbacks: template-heavy.
On a closing note, I wouldn't use this kwargs library simply because there is a number of good enough alternatives in C++ to achieve the same. I personally would opt for 1. or 2. from the (non-exhaustive) list above.