c++ - 如何让 `static_assert` 打印失败时得到的值?

标签 c++ templates c++14 c++17 static-assert

运行这个:

#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)

template< int PathLength >
constexpr const int startfindlastslash(const char (&path)[PathLength]) {
    return PathLength;
}

int main(int argc, char const *argv[])
{
    STATIC_ASSERT( startfindlastslash( "cppdebugger/test_debugger.cpp" ) == 11 );
}

你得到了:

  1. g++ -o main.exe --std=c++14 test_debugger.cpp

    test_debugger.cpp: In function ‘int main(int, const char**)’:
    test_debugger.cpp:1:28: error: static assertion failed: startfindlastslash( "cppdebugger/test_debugger.cpp" ) == 11
     #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
                                ^
    test_debugger.cpp:10:5: note: in expansion of macro ‘STATIC_ASSERT’
         STATIC_ASSERT( startfindlastslash( "cppdebugger/test_debugger.cpp" ) == 11 );
         ^~~~~~~~~~~~~
    
  2. clang++ -Xclang -ast-print -fsyntax-only --std=c++14 test_debugger.cpp > main.exe

    test_debugger.cpp:10:5: error: static_assert failed due to requirement 'startfindlastslash("cppdebugger/test_debugger.cpp") == 11' "startfindlastslash(
          \"cppdebugger/test_debugger.cpp\" ) == 11"
        STATIC_ASSERT( startfindlastslash( "cppdebugger/test_debugger.cpp" ) == 11 );
        ^              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    test_debugger.cpp:1:28: note: expanded from macro 'STATIC_ASSERT'
    #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
                               ^             ~~~~~~~~~~~
    1 error generated.
    

编译器不会告诉它应该获得哪个值,它只是说该值不相等。

最佳答案

我经常发现包裹 static_asserts 很有用。在函数模板中。然后编译器至少会打印错误消息中的函数模板参数。如果您将此策略与@Phil1970 的值(value)模板方法结合起来,您会得到相当不错的结果。

使用 GCC 编译时,以下代码片段会打印包含您的值的错误消息: In instantiation of 'constexpr void assert_equal(const_val<T, A>, const_val<U, B>) [with T = int; T A = 30; U = int; U B = 11]'

Clang 更好:<source>:13:5: error: static_assert failed due to requirement '30 == 11' "Values are not equal!" .

#define MAKE_CONST(x) const_val<decltype(x), x>{}
#define STATIC_ASSERT_EQUAL(x, y) assert_equal(MAKE_CONST(x), MAKE_CONST(y));

template<typename T, T val>
struct const_val {
    constexpr const_val() = default;
    constexpr const_val(T v) {}
};

template<typename T, T A, typename U, U B>
constexpr void assert_equal(const_val<T, A>, const_val<U, B>) {
    static_assert(A == B, "Values are not equal!");
}

template< int PathLength >
constexpr const int startfindlastslash(const char (&path)[PathLength]) {
    return PathLength;
}

int main(int argc, char const *argv[])
{
  STATIC_ASSERT_EQUAL(startfindlastslash( "cppdebugger/test_debugger.cpp" ), 11);
}

这并不完全是您使用的语法,为了方便起见,它涉及一个额外的宏,但希望它足以满足您的目的...

实时代码 here .

关于c++ - 如何让 `static_assert` 打印失败时得到的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59473672/

相关文章:

c++ - 如何在 C++ 中解构二维 vector

c++ - 如何让 Visual Studio 将 .cl 文件视为源代码?

c# - 在 C# 中实现类似 C++ 模板的行为

c++ - 是否可以确保在编译时最多调用一次 constexpr 函数?

c++ - `constexpr` 参数在编译时未知时不调用构造函数

c++ - 二叉树的层序遍历

c++ - boost 序列化 - 从多态存档派生

javascript - 如何从模板添加 SVG g 元素?

html - CSS:右列不再位于菜单栏下方

c++ - 如何构造不可移动不可复制对象的元组?