Why C++ Template function `auto` return type deduction fails on GCC but works on Clang and MSVC

Viewed 101

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?

0 Answers
Related