ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – 在static_assert()中在编译时显示整数

2019-10-06 13:10:14  阅读:219  来源: 互联网

标签:static-assert c c11 macros integer


这是我正在尝试做的简化版本

enum First
{
    a,
    b,
    c,
    nbElementFirstEnum,
};
enum Second
{
    a,
    b,
    c,
    nbElementSecondEnum,
};

static_assert(
    First::nbElementFirstEnum == Second::nbElementSecondEnum,
    "Not the same number of element in the enums.");
/*static_assert(  
    First::nbElementFirstEnum == Second::nbElementSecondEnum, 
    "Not the same number of element in the enums." + First::nbElementFirstEnum + " " + Second::nbElementSecondEnum);*/

但是我希望能够在断言消息中打印First :: nbElementFirstEnum和Second :: nbElementSecondEnum的值(就像在注释版本中显然不起作用).
我尝试使用“#”进行宏连接.
我还尝试使用可变参数模板,用?每个数字并将“0”字符添加到检索到的值中,但我得到的只是一个constexpr char [].

所以我的问题是如何让我的枚举值以字符串文字打印.

可能重复:

C++11 static_assert: Parameterized error messages

Integrate type name in static_assert output?

最有趣的话题是这个:
Printing sizeof(T) at compile time
但是我不希望发出警告或退出代码来了解这些值.

解决方法:

这基本上是有效的,虽然可以稍微省力(通过使V1和V2总和为256的倍数).所以,我认为你的解决方案更加丑陋,但仍然更加强大.

template <int V1, int V2> struct AssertEquality
{
    static const char not_equal_warning = V1 + V2 + 256;
};

template <int V> struct AssertEquality<V, V>
{
    static const bool not_equal_warning = 0;
};

#define ASSERT_EQUALITY(V1, V2) static_assert( \
    AssertEquality<static_cast<int>(V1), \
                   static_cast<int>(V2)>::not_equal_warning == 0, \
    #V1 " != " #V2 );

// ...

ASSERT_EQUALITY(First::nbElementFirstEnum, Second::nbElementSecondEnum);

输出看起来像:

g++ -std=c++0x -c chksz.cpp
chksz.cpp: In instantiation of ‘const char AssertEquality<3, 2>::not_equal_warning’:
chksz.cpp:40:124:   instantiated from here
chksz.cpp:5:53: warning: overflow in implicit constant conversion
chksz.cpp:40:1: error: static assertion failed: "First::nbElementFirstEnum != Second::nbElementSecondEnum"

作为参考,这个原始版本依赖于gcc打印static_assert消息,即使布尔条件根本不编译也是如此.

template <typename Enum1, int Max1, typename Enum2, int Max2>
struct AssertSameSizeEnums;

template <typename Enum1, int EnumMax, typename Enum2>
struct AssertSameSizeEnums<Enum1, EnumMax, Enum2, EnumMax> {};
// only define the special case where Max1 and Max2 have the same integer value

#define ASSERT_SAME_SIZE_ENUMS(E1, M1, E2, M2) static_assert( \
    sizeof(AssertSameSizeEnums<E1, E1::M1, E2, E2::M2>), \
    #E1 "::" #M1 " != " #E2 "::" #M2 );

enum class First {
    a, b, c, nbElementFirstEnum,
};
enum class Second {
    a, b, c, nbElementSecondEnum,
};

ASSERT_SAME_SIZE_ENUMS(First, nbElementFirstEnum, Second, nbElementSecondEnum);

注意我将您的枚举更改为强类型,否则枚举的常量名称会发生​​冲突.如果你有弱类型的枚举,传递给宏的第一个和第二个应该命名封闭的范围.

现在,如果我注释掉其中一个值(因此枚举的大小不同),我得到:

g++ -std=c++0x -c chksz.cpp
chksz.cpp:25:113: error: invalid application of ‘sizeof’ to incomplete type ‘AssertSameSizeEnums<First, 3, Second, 2>’
chksz.cpp:25:1: error: static assertion failed: "First::nbElementFirstEnum != Second::nbElementSecondEnum"

查看整数值在不完整类型错误中的显示方式,以及静态断言中的符号名称?

标签:static-assert,c,c11,macros,integer
来源: https://codeday.me/bug/20191006/1860394.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有