почему оператор обратного преобразования SFINAE не работает? - PullRequest
0 голосов
/ 06 марта 2019
struct A
{
  template <typename T>
  constexpr explicit operator
  std::enable_if_t<
    std::is_same<std::decay_t<T>, int>{},
    int
  >() const noexcept
  {
    return -1;
  }
};

int main()
{
  A a;

  std::cout << int(a) << std::endl;
}

Ошибка clang-7.0.1:

<source>:21:16: error: no matching conversion for functional-style cast from 'A' to 'int'
  std::cout << int(a) << std::endl;
               ^~~~~
<source>:7:22: note: candidate template ignored: couldn't infer template argument 'T'
  constexpr explicit operator
                     ^

1 Ответ

5 голосов
/ 06 марта 2019

Этот шаблон просто не работает для функций преобразования.Проблема в том, чтобы определить, можно ли a преобразовать в int, мы ищем operator int(), но получаем:

std::enable_if_t<std::is_same<std::decay_t<T>, int>{}, int>

Это не выводимый контекст, поэтомумы не находим int.

Вы должны переместить условие в параметр по умолчанию:

template <typename T, std::enable_if_t<std::is_same_v<T, int>, int> = 0>
constexpr explicit operator T() const noexcept { return -1; }

Таким образом, мы можем вывести T и затем позволить SFINAE выполнить егомагия.Обратите внимание, что вам не нужно decay, поскольку у нас нет ссылок.

...