Does put_money hold its argument by value or reference?

The standard ([ext.manip]/6) only defines this specific expression:

out << put_­money(mon, intl);

It is unspecified how mon is stored in the mean time, and it is definitely possible for it to become a dangling reference and be UB.

An "easy" fix is making your own class to know you store the value:

struct money_putter {
    long double value;

    template<class charT, class traits>
    friend std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const money_putter& mon) {
        return os << std::put_money(mon.value);
    }
};


int main() {
    int values[] = {1, 2, 3};
    std::transform(
        std::begin(values), std::end(values),
        std::experimental::make_ostream_joiner(std::cout, ", "),
        [](int i)  {
            return money_putter{i};  // or i + 1
        }
    );
    return 0;
}

You could test it, though this wont tell you anything about whether it is guaranteed, but then as the return type of put_money is not specified, you cannot assume that the returned value does not hold a reference.

...anyhow let's test it:

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <experimental/iterator>

int main() {
    int i = 42;
    std::cout << std::put_money(i) << "\n";
    auto x = std::put_money(i);
    i = 43;
    std::cout << x;    
    return 0;
}

Output with clang:

42
43

So actually the answer is positive. With clang the returned value does hold a reference and the output is the same with gcc. Hence, yes your code has UB.