Customization point for to-string conversion #121
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The use of boost::lexical_cast for default_value and implicit_value has several deficiencies; firstly, with the adoption of std::format in C++20 it is becoming more and more usual for libraries to regard iostreams formatting as deprecated and not provide ostream operator<< overloads for classes. Secondly, the standard library has added ostreams formatting for classes (esp. std::chrono) at different times, making it confusing when code works on one compiler and not another; it is possible to always use the two-argument overloads of default_value and implicit_value, but this is extra repeated work for the user and encourages providing string literals which may get out of sync with the actually provided default/implicit value. Finally, as a general point, when validate() is customized it may use a different format than iostreams (often terser and avoiding characters that are difficult to supply on the command line).
In conclusion, it would be useful to lexical_cast to std::string indirectly, via a customization point that can be customized by the user specifically for Boost.ProgramOptions.
This PR supplies a customization point in boost::program_options namespace with primary overload:
The first parameter is the value being textualized (by default_value or implicit_value single-argument overloads). The second parameter is mainly for ADL and disambiguation, but also if non-null it provides access to the 'value_semantic' being modified. The third parameter is for overload resolution, as with 'validate'.
There is one overload provided, for std::vector:
This mirrors the overload of 'validate' for std::vector, since it would be surprising for 'make_textual' to work where 'validate' does. It also illustrates how to recursively invoke 'make_textual', and that the 'value_semantic' parameter may be null. This is just conceivably a breaking change if some user has provided operator<< for std::vector but not for T for some type T, but this seems very unlikely.