Convenience function wrapping C++17's std::sample for distance=1 case
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.