Подтвердить что ты не робот

Как определить, есть ли функция func. является constexpr? и отметить другую функцию. constexpr в зависимости от этого?

Предполагая, что у меня есть некоторый шаблон функции f1:

template<typename f2>
int f1(int i, int j) noexcept {
  return i + j + f2(i, j);
}

существует ли способ определить, может ли f2(i, j) быть constexpr. (независимо от того, является ли это функтором или функтором), и поэтому отметьте f1<f2> как constexpr тоже?

Я думаю использовать SFINAE здесь как-то, но не нашел, как обнаружить constexpr с помощью свойств типа

4b9b3361

Ответ 1

Вы можете пометить f1 как constexpr.

template<typename f2>
constexpr int f1(int i, int j) noexcept {
  return i + j + f2(i, j);
}

Функция шаблона f1 будет constexpr iif f2 is.

если f2 нет, вы получите ошибку, только когда используете f1 в выражении постоянной компиляции.

Демо

Ответ 2

Самый простой способ проверить, является ли функция (например, foo) constexpr, назначать ее возвращаемое значение на constexpr, как показано ниже:

  constexpr auto i = foo();

если возвращаемое значение не соответствует constexpr, компиляция завершится с ошибкой.

Если вы хотите, чтобы тест SFINAE проверял, является ли функция (например, foo) constexpr, вы можете использовать свойство std::integral_constant:

std::integral_constant<int, foo()>::value

Live Demo

Ответ 3

Итак, наконец, используя подсказку Jarod42, я напишу и протестировал этот пример:

#include <string>
std::string S = "123567876";

constexpr size_t p() noexcept {
  return 10U;
}

template<const size_t = size_t()>
constexpr size_t f(size_t i, size_t j) noexcept {
  return std::move(i + j + S.size() + p());
}

#include <iostream>
int main() {
  // static constexpr const auto v = f<>(1U, 2U); // error!
  std::cout << f(1U, 2U) << "\n";
  return 0;
}

теперь он работает правильно, я тестировал его с помощью GCC онлайн, как с С++ 11, так и с C + 14.


Вы можете доказать, что это будет действительно constexpr, если возможно, удалив '+ S.size()':

...
  return std::move(i + j + p());
...

и uncommenting значение constexpr:

...
  static constexpr const auto v = f(1U, 2U);
  std::cout << v << "\n";
...

см. здесь.


Р. С. Спасибо, ребята!