This answer does a great job at answering my question, but I thought I'd supply a more generic solution to the problem of ensuring the object output to an ostream_joiner
takes no dangling references, one that uses a lambda to capture those references:
#include <type_traits>
#include <ostream>
template<typename F>
class put_invocation_t {
public:
constexpr put_invocation_t(F const& f) : f(f) {}
constexpr put_invocation_t(F&& f) : f(std::move(f)) {}
template<class charT, class traits>
friend std::basic_ostream<charT, traits>& operator<<(
std::basic_ostream<charT, traits>& os, put_invocation_t const& pi
) {
return pi.f(os);
}
private:
F f;
};
// or use a deduction guide in C++17
template<typename F>
put_invocation_t<std::decay_t<F>> put_invocation(F&& f) {
return put_invocation_t<std::decay_t<F>>(std::forward<F>(f));
}
Used as
std::transform(
std::begin(values), std::end(values),
std::experimental::make_ostream_joiner(std::cout, ", "),
[](long double v) {
return put_invocation([=](auto& os) -> auto& {
return os << std::put_money(v + 1);
});
}
);
This has the bonus of also scaling to outputing multiple values, by using something like the following within the transform
:
return put_invocation([=](auto& os) -> auto& {
return os << "Value is: " << std::put_money(v + 1);
});
[](const int& i){...}
might work around any potential lifetime issues? – Progestationali + 1
– Lupienstringstream
inside the lambda, dump the result ofput_money
in there, and then return the stream's string contents. But that has all the overhead that comes with stringstream and would be somewhat inefficient. – Italicizeint
is an invalid argument tostd::put_money
; the argument must be eitherlong double
or some specialization ofstd::basic_string
. It seems like for along double
, either implementation would be valid, since the only use of the saved argument is to pass it tostd::money_put<CharT, OIter>::put
, which takes the number by value. Though the string version takes the string by reference, and some custom override ofmoney_put::do_put
might do something weird with its argument's address. – Apcint
can be converted tolong double
. Either way, updated for clarity. @0x5453, updated to make your point moot too. – Lupien