【问题标题】:How can you compare two character strings statically at compile time如何在编译时静态比较两个字符串
【发布时间】:2015-02-13 22:49:44
【问题描述】:

我想创建一个可以比较 2 个字符串的宏,如果条件不满足,则会发出编译时错误。这可以看作是一个编译时断言。

我不知道我该怎么做。

例如:

STATIC_COMPARE("THIS STRING","THIS STRING") -> would emit a compile time error
STATIC_COMPARE("THIS STRING","THIS OTHER STRING) -> wouldn't emit a compile time error.

宏看起来像

#define STATIC_COMPARE(str1,str2) if (str1==str2) emit an error with a message

所以我想问题归结为能够在编译时比较两个字符串。

【问题讨论】:

标签: c++ xcode macros compiler-errors gnu


【解决方案1】:

从 C++17 开始,std::string_view 可用。支持 constexpr 比较:

#include <string_view>

constexpr bool strings_equal(char const * a, char const * b) {
    return std::string_view(a)==b;
}

int main() {
    static_assert(strings_equal("abc", "abc" ), "strings are equal");
    static_assert(!strings_equal("abc", "abcd"), "strings are not equal");
    return 0;
}

Demo

【讨论】:

    【解决方案2】:

    您可以通过使用 constexpr 函数在 C++11 中做到这一点:

    constexpr bool strings_equal(char const * a, char const * b) {
        return *a == *b && (*a == '\0' || strings_equal(a + 1, b + 1));
    }
    

    (See a demo)

    在 C++11 之前不可能做到这一点,但需要注意的是,许多编译器会将相等的字符串文字编译为指向同一位置的指针。在这些编译器上,直接比较字符串就足够了,因为它们都将被评估为相等的指针。

    【讨论】:

    • 在同一网站上使用 coliru。用 1y 在 clang 上试了一下,效果很好。将删除我的评论。
    • 我试图让它在 Xcode 中工作 - 无法。也许还有另一种方法可以在该环境中进行静态断言。我找到了一些资源,但无法使其正常工作。 en.cppreference.com/w/cpp/language/static_assert
    • “警告许多编译器会将相等的字符串文字编译为指向同一位置的指针。”字符串文字没有内存位置。
    • @Nils 字符串文字创建一个具有静态存储持续时间的未命名数组。这个数组有一个内存位置,这就是字面量所指的。所以是的,文字导致内存位置存在,可以与任何其他指针进行比较。
    【解决方案3】:

    这可以在 C++ 11 中使用 constexpr 完成。通过定义递归函数,您可以检查字符串是否相等。

    constexpr bool isequal(char const *one, char const *two) 
    {
        return (*one && *two) ? (*one == *two && isequal(one + 1, two + 1)) : (!*one && !*two);
    }
    
    static_assert(isequal("foo", "foo"), "this should never fail");
    static_assert(!isequal("foo", "bar"), "this should never fail");
    

    感谢 Johannes Schaub,我使用了这段代码,你可以看到完整的 SO 帖子here

    【讨论】:

      【解决方案4】:

      您可以使用constexpr 函数。这是 C++14 的方式:

      constexpr bool equal( char const* lhs, char const* rhs )
      {
          while (*lhs || *rhs)
              if (*lhs++ != *rhs++)
                  return false;
          return true;
      }
      

      Demo.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-21
        • 1970-01-01
        • 2021-07-05
        • 1970-01-01
        • 2022-06-29
        • 1970-01-01
        • 2019-01-14
        相关资源
        最近更新 更多