【问题标题】:C++ using string_view in constexpr ifC++ 在 constexpr if 中使用 string_view
【发布时间】:2021-06-23 04:51:57
【问题描述】:

我想像这样在编译时比较字符串视图:

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 的 operator== 是 constexpr。一个解决方案是声明参数 constexpr 但这是不可能的。

那么我怎样才能有一个 constexpr 函数在编译时检查这些匹配?

【问题讨论】:

  • if constexpr 中删除constexpr
  • 您的 str 参数不是 constexpr,因此表达式 str == "abc" 不是 constexpr。请注意,constexpr 函数可以在运行时调用,这意味着 str 可能是运行时已知值,因此您不能始终保证该值在编译时已知。
  • @KamilCuk 如果我删除 constexpr,我无法保证代码将在编译时执行,并且我无法在最后创建 static_assert(false "invalid str") 以确保 str 有效。
  • 如果函数是在编译时调用的,那么无论if是不是constexpr,很明显body也是在编译时执行的。如果您必须处理不同的类型和模板参数,if constexpr 最有用。
  • 如果你想确保你的代码在编译时运行,并且你有 C++20,你可以改用函数consteval

标签: c++ constexpr string-view


【解决方案1】:

我怎样才能有一个 constexpr 函数来检查这些匹配项

只需从ifs 中删除constexpr

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 调用您的函数。

【讨论】:

  • 好吧,看起来不错,但是如果我有一个函数foo(bool match) 并像foo(isMatch("test"sv)) 一样调用它,我可以在编译时执行吗?在这种情况下,isMatch 是编译时间吗?因为我可以定义一个constexpr bool match = isMatch("test"sv)然后调用foo(match)但是太烦人了,我想直接传过去
  • 您必须将“保证是编译时间”与“是编译时间”分开。理论上,当您编写foo(1 ==1) 时,没有保证 1 == 1 比较将在编译时执行。但实际上,任何编译器都会对其进行优化。与constexpr 函数类似。 constexpr 函数可能在运行时执行。但是任何自尊的编译器都会对其进行优化。所以回答foo(isMatch("test"sv))? Does the isMatch is compile time 不能保证,但它会的。如果您想要这种保证,请将该意图明确传达给编译器。
猜你喜欢
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-01
  • 1970-01-01
相关资源
最近更新 更多