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?