enable_if не работает в Visual Studio при использовании функции constexpr в качестве аргумента

В настоящее время я борюсь с Visual Studio 2017 (компиляция с использованием /std:c++latest, если это поможет).

Рассматриваемый код просто выбирает специализацию структуры на основе результата некоторой шаблонной функции constexpr. GCC и clang без труда компилируют его.

Вот мой MCVE:

#include <type_traits>

struct A {
  enum {
    test_trait = true
   };
};

template<typename T>
constexpr int choose() {
  return T::test_trait;
}

template<typename T, typename Enable=void>
struct Chosen;

template<typename T>
struct Chosen<T, std::enable_if_t<choose<T>() == 1>> {};

void foo() {
  // This works
  constexpr int chosen = choose<A>();
  static_assert(chosen == 1, "");

  // This resolves to the undefined struct.
  using Chosen_t = Chosen<A>;
  Chosen_t x;
  (void)x;
}

choose() на самом деле немного сложнее в моей кодовой базе, но static_assert все еще компилируется и проверяет нормально.

Я вроде бы предположил, что если static_assert компилируется, то нет никаких оснований для enable_if быть неспособным сделать свою магию. Я ошибаюсь? Я предполагаю, что «возможно» T технически не является зависимым типом enable_if ... Но если бы это было так, я бы ожидал, что GCC и лязг ударит меня по запястью.

Я могу обойти это, обернув результат choose() в std::integral_constant, примерно так:

template<typename T> 
struct Chooser : public std::integral_constant<int, choose<T>()> {};

template<typename T>
struct Chosen<T, std::enable_if_t<Chooser<T>::value>> {};

Но я бы действительно не хотел прыгать через этот обруч.

Должно ли разрешение шаблонов разрешать это так, как я ожидаю? Я беспокоюсь, что код на самом деле неверен, и GCC и Clang просто снисходительны ко мне.

11
задан Frank 10 September 2017 в 18:54
поделиться