如何使`static_assert`打印失败时得到的值?

问题描述 投票:2回答:2

运行此:

#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.
    

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

c++ templates c++14 c++17 static-assert
2个回答
1
投票
[这实际上不是对“如何使static_assert打印值”的答案,而是对OP为什么要获得其行为的解释。 ]

c ++++之前的版本,static_assert具有两个参数。

第一个是要求值的表达式,第二个是当表达式的求值不为true时要打印的消息。

[当您定义STATIC_ASSERT宏时,您正在向static_assert提供要打印的消息-并且它正在为您打印该消息。


0
投票
我经常发现将static_asserts包装在功能模板中很有用。然后,编译器将至少在错误消息中打印功能模板参数。如果将此策略与@ Phil1970的值模板方法结合使用,则会获得相当不错的结果。

使用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]'

C声更好:<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

© www.soinside.com 2019 - 2024. All rights reserved.