Вперед объявленные функции и SFINAE - PullRequest
5 голосов
/ 06 января 2020

Я столкнулся с интересным шаблоном в библиотеке concontexpr .

Согласно readme, идея заключается в том, что, учитывая функцию автоматического возврата типа, объявленную вперед, тип возврата может ' не может быть выведено до фактического определения функции, и это позволяет некоторым SFINAE magi c.

Я думал, что эта функция языка может быть полезна для нескольких других идей, и провел некоторые эксперименты с ней, и это выглядит например, g cc и clang ведут себя по-разному, когда функция не является шаблоном: g cc работает так же, в то время как clang сообщает об ошибке.

И на основании того, что показывает сообщение об ошибке clang, возможно, это не должно работать даже для шаблона?

Итак, вопросы:

  • Является ли часть шаблона (разрешенная как clang, так и g cc) разрешенной стандартом?
  • какой компилятор верен в не шаблонной версии?

Упрощенный код (также для godbolt ):

struct S {};

constexpr auto f1();

template <typename T>
constexpr auto f2(T);

// compilation error with clang:
// function with deduced return type cannot be used before it is defined
template <typename T, typename = decltype(f1())>
void test1_1() {}
template <typename T>
void test1_1() {}

// compiles with clang, even if f2 will never be defined
template <typename T, typename = decltype(f2<T>(T{}))>
constexpr int test1_2(int) { return 1; }
template <typename T>
constexpr int test1_2(float) { return 2; }

/////////////////

int g1_2() {
  return test1_2<S>(0);
}

constexpr auto f1() { return 1; }

// comment-uncomment this:
// the value returned by g2_@ will change
// /*
template <typename T>
constexpr auto f2(T) {
  return 2;
}
// */

// can be defined here
template <typename T, typename = decltype(f1())>
void test2_1() {}

int g2_2() {
  return test1_2<S>(0);
}

Примечание: Первоначально я также упоминаю Если бы он вел себя по-разному с друзьями, и, похоже, он работает без автоматического возврата - это были ошибки пользователя с моей стороны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...