Converting std::string to int without Boost
There's a few things that jump out at me both in your implementation and standard options you missed. A few (scattered) thoughts follow.



Returning a default if you care about error checking doesn't make sense. How would you determine if conversion failed if there's not an integer available for use as a sentinel? You are basically doing the same thing atoi does except your default is flexible instead of 0.



Have you considered [strtol][1]? It's basically atoi with error checking capabilities. It's the fastest string to int converter you're likely going to get:

long string_to_long(const std::string&amp; str, long default_value, int base = 10) {
    char* parse_end = NULL; //nullptr if C++11, though really you don't have to initialize this
                            //since strol is guaranteed to initialize it. I just like to avoid
                            //unitialized variables.
    long val = strtol(str.c_str(), &amp;parse_end, base);
    if (parse_end == str.c_str() + str.size()) {
        return val;
    } else {
        return default_value;
    }
}


Note: strtol ignores leading whitespace. The function I've written above errors for trailing whitespace (or trailing anything). In other words, " 3" is fine, but "3 " would error.



The idiomatic way to do this in C++ would be to use a string stream:

int string_to_int(const std::string&amp; str, int def)
{
    std::istringstream ss(str);
    int i;
    if (!(ss &gt;&gt; std::noskipws &gt;&gt; i)) {
        //Extracting an int failed
        return def;
    }
    char c;
    if (ss &gt;&gt; c) {
        //There was something after the int
        return def;
    }
    return i;
}


In terms of performance, strtol will likely be faster than this. This does have a useful advantage though that it can be made highly generic with simple templating (this is the essential idea behind boost::lexical_cast actually, but this doesn't use exceptions):

template&lt;typename ResultType&gt;
ResultType lexical_cast(const std::string&amp; str, const ResultType&amp; default_value = ResultType()) {
    std::istringstream ss(str);
    ResultType result;
    if (!(ss &gt;&gt; std::noskipws &gt;&gt; result)) {
        return default_value;
    }
    char c;
    if (ss &gt;&gt; c) {
        return default_value;
    }
    return result;
}




If you don't want to use exceptions, but you want to be able to detect errors, you're going to have to use a flag. You basically have two options of how to handle that. You can use a boolean flag and return the value, or you can use a boolean reference parameter and return the value. Which route you take really depends on how you want to use the code, but I would probably return the value. That lets you ignore errors if you want to, but it still doesn't force you to. I might do something like this:

template&lt;typename ResultType&gt;
ResultType lexical_cast(const std::string&amp; str, bool&amp; success) {
    std::istringstream ss(str);
    ResultType result;
    success = true;
    if (!(ss &gt;&gt; std::noskipws &gt;&gt; result)) {
        success = false;
    }
    char c;
    if (ss &gt;&gt; c) {
        success = false;
    }
    return result;
}

template&lt;typename ResultType&gt;
ResultType lexical_cast(const std::string&amp; str) {
    bool ignore;
    return lexical_cast&lt;ResultType&gt;(str, ignore);
}


This gives you both options of detecting an error or ignoring one. You could even build more on top of this to have one that returns a default value:

template&lt;typename ResultType&gt;
ResultType lexical_cast(const std::string&amp; str, const ResultType&amp; default_value = ResultType()) {
    bool success;
    ResultType val(lexical_cast&lt;ResultType&gt;(str, ignore));
    if (success) {
        return val;
    } else {
        return default_value;
    }
}




Don't check for classes of characters manually. Just use the cctype header's functions (isspace, isdigit, etc).



You loop is way over complicated:

bool all_digit = true;
for (std::string::size_type i = 0, l = str.size(); i &lt; l; ++i) {
    if (!std::isdigit(str[i])) { 
       all_digit = false;
        break;
    }
}

if (all_digit) { ... }


Or, allowing leading/trailing whitespace:

std::string::size_t i = 0;
const std::string::size_t len = str.size();
for (; i &lt; len &amp;&amp; std::isspace(str[i]); ++i) { /* empty */ }
for (; i &lt; len &amp;&amp; std::isdigit(str[i]); ++i) { /* empty */ }
for (; i &lt; len &amp;&amp; std::isspace(str[i]); ++i) { /* empty */ }
const bool all_digits = (i == len);