Convenience function wrapping C++17's std::sample for distance=1 case C++ has the function std::sample which randomly samples from a range and places the results via an output iterator. My goal is to create a utility that directly returns a single value in the event that we only want to sample a single random element from the container.
#include &lt;iostream&gt;
#include &lt;random&gt;
#include &lt;algorithm&gt;
#include &lt;iterator&gt;
#include &lt;unordered_set&gt;
#include &lt;array&gt;

template&lt;class InputIt, class URBG&gt;
auto singleRandomSample(InputIt t_begin, InputIt t_end, URBG&amp;&amp; rng)
{
    using value_type = typename std::iterator_traits&lt;InputIt&gt;::value_type;
    std::array&lt;value_type, 1&gt; out;
    std::sample(t_begin, t_end, out.begin(), 1, rng);
    return out.at(0);
}


int main()
{
    std::default_random_engine rng{ std::random_device{}() };
    std::unordered_set&lt;char&gt; vowels{ 'a', 'e', 'i', 'o', 'u', 'y' };
    for (std::size_t i = 0; i &lt; 10; ++i)
    {
        auto randomVowel = singleRandomSample(vowels.begin(), vowels.end(), rng);
        std::cout &lt;&lt; &quot;Random vowel: &quot; &lt;&lt; randomVowel &lt;&lt; '\n';
    }
}

This function creates a temporary container out to which a single element is added, then returns that element by value. It uses an std::array because I know I only need room for a single element, although if I decided it was important to be able to use this with non-default-constructible types I could switch to a std::vector and a std::back_inserter.
Is it correct to call std::sample using rng as an argument directly, or should I be using std::forward(rng)?
It feels slightly clunky to have an entire temporary container just to store a single value that's immediately returned. Is there another way this functionality could be implemented?
A pointer is an iterator.
template &lt;typename InputIterator, typename URBG&gt;
auto singleRandomSample(InputIterator first, InputIterator last, URBG&amp;&amp; rng)
{
    using value_type = typename std::iterator_traits&lt;InputIterator&gt;::value_type;

    auto result = value_type{};

    std::sample(first, last, &amp;result, 1, std::forward&lt;URBG&gt;(rng));

    return result;
}

Or, with a better, C++20 interface:
template &lt;std::input_iterator I, std::sentinel_for&lt;I&gt; S, typename URBG&gt;
    requires std::uniform_random_bit_generator&lt;std::remove_reference_t&lt;URBG&gt;&gt;
auto singleRandomSample(I first, S last, URBG&amp;&amp; rng)
{
    auto result = std::iter_value_t&lt;I&gt;{};

    std::ranges::sample(first, last, &amp;result, 1, std::forward&lt;URBG&gt;(rng));

    return result;
}

template &lt;std::input_range R, typename URBG&gt;
    requires std::uniform_random_bit_generator&lt;std::remove_reference_t&lt;URBG&gt;&gt;
auto singleRandomSample(R&amp;&amp; r, URBG&amp;&amp; rng)
{
    auto result = std::ranges::range_value_t&lt;R&gt;{};

    std::ranges::sample(r, &amp;result, 1, std::forward&lt;URBG&gt;(rng));

    return result;
}

This requires the value type of the range to be default-constructible, but you were already counting on that with the array solution.
If you want a solution that does not require default construction, you could probably do something like using an optional type—like std::optional, or std::variant with std::monostate—and a custom output iterator that does an emplace into it.