С++ с использованием string_view в constexpr, если

Я хочу сравнить представления строк во время компиляции следующим образом:

constexpr bool isMatch(const string_view str) {
  if constexpr (str == "firstMatch"sv) {
      return true;
  } else if constexpr (str == "secondMatch"sv) {
     return true;
  }
  // ....
}

И функция вызывается так:

isMatch("something"sv);

Что, очевидно, постоянно, потому что это правильно в коде.

Но компилятор говорит, что выражение внутри if constexpr «не является константой». Но оператор == для string_view — это constexpr. Решением было бы объявить параметр constexpr, но это невозможно.

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


person Jojolatino    schedule 26.03.2021    source источник
comment
Удалить constexpr из if constexpr.   -  person KamilCuk    schedule 26.03.2021
comment
Ваш параметр str не является constexpr, поэтому выражение str == "abc" не является constexpr. Обратите внимание, что constexpr функции могут вызываться во время выполнения, что означает, что str может быть известным значением во время выполнения, поэтому вы не всегда можете гарантировать, что значение известно во время компиляции.   -  person Timo    schedule 26.03.2021
comment
@KamilCuk Если я удалю constexpr, у меня нет гарантии, что код будет выполнен во время компиляции, и я не смогу поставить static_assert(false "invalid str") в конце, чтобы убедиться, что строка действительна.   -  person Jojolatino    schedule 26.03.2021
comment
Если функция вызывается во время компиляции, тело, очевидно, также выполняется во время компиляции, независимо от того, является ли if constexpr или нет. if constexpr в основном полезен, если вам приходится иметь дело с разными типами и аргументами шаблона.   -  person Timo    schedule 26.03.2021
comment
constexpr этим не занимается. Чтобы он точно вызывался во время компиляции, вы можете сделать как constexpr bool var = isMatch(..). and I could not make a Потому что нельзя - аргументы функции могут меняться, они не constexpr.   -  person KamilCuk    schedule 26.03.2021
comment
Если вы хотите убедиться, что ваш код запускается во время компиляции, и у вас есть C++20, вы можете вместо этого сделать функцию consteval.   -  person Timo    schedule 26.03.2021


Ответы (1)


как я могу иметь функцию constexpr, которая проверяет такие совпадения

Просто удалите constexpr из ifs.

constexpr bool isMatch(const string_view str) {
  if (str == "firstMatch"sv) {
      return true;
  } else if (str == "secondMatch"sv) {
     return true;
  }
  return false;
}

std::string_view::operator== это constexpr, так что все в порядке.

во время компиляции?

Вызовите свою функцию в контексте времени компиляции. Нравиться:

#include <array>
#include <cassert>
#include <string_view>
using namespace std::literals;

constexpr bool isMatch(const std::string_view str) {
  if (str == "firstMatch"sv) {
      return true;
  } else if (str == "secondMatch"sv) {
     return true;
  }
  return false;
}

int main() {
    std::array<int, isMatch("secondMatch"sv)> arr;
    static_assert(isMatch("firstMatch"sv));
    constexpr bool var = isMatch("No match for you!"sv);
}

В C++20 вы можете убедиться, что ваша функция вызывается только во время компиляции с помощью consteval.

person KamilCuk    schedule 26.03.2021
comment
Хорошо, это выглядит нормально, но могу ли я выполнить время компиляции, если у меня есть функция foo(bool match) и я вызываю ее как foo(isMatch("test"sv))? Является ли isMatch временем компиляции в этом случае? Потому что я мог бы определить constexpr bool match = isMatch("test"sv), а затем вызвать foo(match), но это слишком раздражает, я хотел бы передать его напрямую - person Jojolatino; 26.03.2021
comment
Вы должны разделить гарантированное время компиляции и время компиляции. Теоретически, когда вы пишете foo(1 ==1), нет гарантии, что 1 == 1 сравнение будет выполнено во время компиляции. Но практически любой компилятор его оптимизирует. Это похоже на функцию constexpr. Функция constexpr может выполняться во время выполнения. Но любой уважающий себя компилятор его оптимизирует. Таким образом, чтобы ответить foo(isMatch("test"sv))? Does the isMatch is compile time, нет никакой гарантии, но это будет. Если вам нужна эта гарантия, явно сообщите об этом намерении компилятору. - person KamilCuk; 26.03.2021