Eliminating repetitiveness in code to test hash functions
Your code does seem open to some improvement. Right now, you're not really getting much good out of using a pointer to a function. You could just about as well invoke each hash function directly in findLowHash as call it via a pointer in foundLow.

In this case, we have a number of functions that all have the same signature, so we can create an array of the pointers to functions. Of course, array should also set off alarm bells--you should almost always prefer std::array or std::vector. In this case, I'll use st::vector, but if you're using a compiler new enough to include it, std::array would be an excellent choice as well.

typedef unsigned int (*hash)(std::string const &amp;key);

std::vector&lt;hash&gt; hashes{
    RSHash, JSHash, PJWHash, ELFHash, BKDRHash, 
    SDBMHash, DJBHash, DEKHash, FNVHash, BPHash, APHash
};


Depending on the age of compiler you're using, it might not support the braced init-list like I've used above. At that point, it's open to argument that (under the circumstances) it would be easier to use an actual array instead. 

In any case, once you have your pointers to functions in something you can index like array, you can use a loop to walk through the array of functions, and use each function in turn:

for (int h=0; h&lt;hashes.size(); h++)
    for (int i=0; i&lt;100000; i++) {
       incrStr(key);
       carryStr(key);
       if (hashes[h](key) &lt; 10000) {
           std::cout &lt;&lt; // ...
           break; // breaks inner loop, so goes to testing next hash function
       }
    }


Again, if you have a new enough compiler (C++11) available, you can make the outer loop a little prettier using a range-based for loop:

for (auto &amp;&amp;hash : hashes) 
    // ...
    if (hash(key) &lt; 10000) 
        // ...


Once you've done that, there are a few more fairly obvious points, such as replacing the magic numbers like 100000 and 10000 with defined constants with more meaningful names.