C++ template to randomly choose from N elements with uniform distribution There is a nice algorithm to randomly choose an element from a list in a single pass:

Pass through the list keeping the element chosen so far (X) and the number of elements processed (N). When processing element Y, let X:=Y with probability 1/N. When nothing is left, return X.

I implemented this using templates:

template &lt;typename T&gt;
const T&amp; chooseImpl(T const&amp; cur, int total) {
  return cur;
}

template &lt;typename T, typename... Args&gt;
const T&amp; chooseImpl(T const&amp; chosen, int total,  T const&amp; next, Args... rest) {
  const T&amp; nextChosen = (rand() % total == 0) ? next : chosen;
  return chooseImpl(nextChosen, total + 1, rest...);
}

template &lt;typename T, typename... Args&gt;
const T&amp; choose(T const&amp; first, Args... rest) {
  return chooseImpl(first, 2, rest...);
}


Example usage:

choose(1, 2, 3, 4, 5, 6); // returns a random number between 1 and 6.
choose(1); // always returns 1.


I only have a problem when choosing from C strings:
    choose("one", "two", "three");


  note:   template argument deduction/substitution failed:
  
  deduced conflicting types for parameter ‘const T’ (‘char [4]’ and ‘const char*’)
Here's a version of your code which works with C-Strings by using std::decay to turn any array arguments into pointers.

This also uses perfect forwarding in the recursion, to preserve argument types, just in case unconditional conversion to a const reference is inappropriate.

I'm making this Community Wiki, because it's more of an answer to your question about C-Strings, rather than a code review (ok, little review: rand() is usually so poorly implemented, you should use something from &lt;random&gt;, like std::mt19937, otherwise, thumbs up!).

#include &lt;iostream&gt;
#include &lt;type_traits&gt;
#include &lt;utility&gt;
#include &lt;string&gt;
#include &lt;cstdlib&gt;

template &lt;typename T&gt;
using decay_t = typename std::decay&lt;T&gt;::type;

template &lt;typename T&gt;
decay_t&lt;T&gt; chooseImpl(T&amp;&amp; cur, int total) {
  return cur;
}

template &lt;typename T, typename U, typename... Args&gt;
decay_t&lt;T&gt; chooseImpl(T&amp;&amp; chosen, int total,  U&amp;&amp; next, Args&amp;&amp;... rest) {
  decay_t&lt;T&gt; nextChosen = (std::rand() % total == 0) ? next : chosen;
  return chooseImpl(nextChosen, total + 1, std::forward&lt;Args&gt;(rest)...);
}

template &lt;typename T, typename... Args&gt;
decay_t&lt;T&gt; choose(T&amp;&amp; first, Args&amp;&amp;... rest) {
  return chooseImpl(std::forward&lt;T&gt;(first), 2, std::forward&lt;Args&gt;(rest)...);
}

int main() {
    std::srand(time(0));
    for(int i=0; i&lt;4; ++i) {
        auto c = choose("one", "two", "three");
        std::cout &lt;&lt; c &lt;&lt; ' ';
    }
    std::cout &lt;&lt; '\n';
    for(int i=0; i&lt;4; ++i) {
        auto c = choose(256, 512, 1024, 13);
        std::cout &lt;&lt; c &lt;&lt; ' ';
    }
    std::cout &lt;&lt; '\n';
    const std::string s[7] = {"Aa", "Bb", "Cc", "Dd", "Ee", "Ff", "Gg"};
    for(int i=0; i&lt;4; ++i) {
        auto c = choose(s[0],s[1],s[2],s[3],s[4],s[5],s[6]);
        std::cout &lt;&lt; c &lt;&lt; ' ';
    }
    std::cout &lt;&lt; '\n';
}


Here is an example of the output:

two three one two 
13 1024 1024 256 
Bb Ff Ee Ee