I am trying to build the following code:
#include <functional>#include <iostream>#include <limits>#include <locale>#include <sstream>#include <string>#include <type_traits>const std::locale defaultLocale = std::locale("");template <typename T, const std::locale& locale = defaultLocale>auto convert(const std::string& str) { auto instream = std::istringstream{str}; instream.imbue(locale); T result; instream >> result; return result;}template <>auto convert<std::string>(const std::string& val) { return val;}template <typename T>T env(const std::string& var, T deflt, std::function<T(const std::string&)> transform = convert<T>) { auto envVar = std::getenv(var.c_str()); if (envVar == nullptr) return (deflt); try { return transform(var); } catch (std::exception& ex) { return (deflt); }}int main(int argc, char** argv) { int n = 0; auto stupido2 = env<int>("PATH", n); return 0;}
Here's the compiler explorer link: https://godbolt.org/z/HAAr2-
I tried to go back even to clang 5.0, and it works.
However, If I change the template functions definitions to the following (replacing auto
with T
and std::string
:
template <typename T, const std::locale& locale = defaultLocale>T convert(const std::string& str) { auto instream = std::istringstream{str}; instream.imbue(locale); T result; instream >> result; return result;}template <>std::string convert<std::string>(const std::string& val) { return val;}
It works. Is it a bug in GCC or in MSVC/Clang? Some compiler extension that I should turn on for GCC?