C++ conversion from std::string to arithmetic type using std::locale::classic()
I see two things I'd change here.

The first is that right now it supports only conversion from string to the specified (arithmetic) type. Sometimes you want (for example) to convert to a string, not just from one. To support that, we can add a second template parameter for the type of the input argument.

My second big point is that you're starting from a problem where the locale to use was hard-wired into boost::lexical_cast. But instead of fixing (what seems to me like) the real problem, you've just hard-wired a different locale.

Instead of that, I'd prefer to specify a locale to use by default, but also allow the user to specify a locale to use for the conversion, if they choose to do so.

Putting those together, we get a function something like this:

template&lt;typename T, typename U&gt;
inline auto lexical_cast(U const&amp; in, std::string const &amp;name = "C")
{
    std::stringstream istr;
    istr.imbue(std::locale(name));
    istr &lt;&lt; in;

    std::string str = istr.str(); // save string in case of exception

    T val;
    istr &gt;&gt; val;

    if (istr.fail())
        throw std::invalid_argument(str);

    return val;
}


Now we can do things like:

// Treat as German input
auto x = lexical_cast&lt;double&gt;("1.234,567", "de");


or:

// convert to string in user's locale
auto s = lexical_cast&lt;std::string&gt;(123456.78, "");


Finally, I'd note one basic difference between this and boost::lexical_cast. This throws an exception if and only if it is unable to convert the input to a result of the output type (at all). Boost lexical_cast not only requires that you be able to convert the input to the output type, but also that when the conversion completes that it consume the entire input.

Consider, for example, something like:

int x = lexical_cast&lt;int&gt;("1 x");


With your lexical_cast, this will succeed because it successfully converted the 1 to an int. With Boost lexical_cast, this will throw an exception because even though it converted 1 to an int, that didn't use the x.