C++ 断言宏参数的完整性

C++ 断言宏参数的完整性,c++,c++11,static-assert,C++,C++11,Static Assert,我试图创建一个宏,静态地断言它的参数是一个严格的正整数。这是在我的许多其他遗留宏中使用的,到目前为止,这些宏只是假设它们的参数的完整性,而没有检查它们的完整性 简而言之,如果我有一个条目,如: “4”、“24”、“42324”等 我希望静态_断言失败,如果参数是沿着这条线的 “4.0”、“3.00”、“2.99”、“3.01”、“-5”、“45n3mn”、“0”、“01”、“002”等,以及空条目 基本上,仅当宏中的参数是干净的整数字符串时,我才希望通过assert传递,这是通过以下“算法”实现

我试图创建一个宏,静态地断言它的参数是一个严格的正整数。这是在我的许多其他遗留宏中使用的,到目前为止,这些宏只是假设它们的参数的完整性,而没有检查它们的完整性

简而言之,如果我有一个条目,如:

“4”、“24”、“42324”等

我希望静态_断言失败,如果参数是沿着这条线的

“4.0”、“3.00”、“2.99”、“3.01”、“-5”、“45n3mn”、“0”、“01”、“002”等,以及空条目

基本上,仅当宏中的参数是干净的整数字符串时,我才希望通过assert传递,这是通过以下“算法”实现的:

(1) 若字符串化的参数不仅仅是数字,那个么就失败了

(2) 如果第一个字符为“0”,则失败

(3) 如果为空,则失败

下面是我目前拥有的,但由于错误“C2057:预期的常量表达式”(我正在使用MSVS2013,但也希望构建与g++4.8兼容的代码)而无法编译。我不知道如何从static_断言中“调用”std::string方法

#define MyStaticAssert_isInt(num, message) \
    static_assert(std::string(#num).find_first_not_of("0123456789") == std::string::npos, message) \
    static_assert(std::string(#num).front() != '0', message) \
    static_assert(!std::string(#num).empty(), message)

提前谢谢

您可以尝试以下用户定义的文字:

#include <cstddef>
#include <string>

constexpr bool operator ""_pure(char const * s, std::size_t len)
{
  return len == 0 ||
         ('0' <= s[0] && s[0] <= '9' && operator ""_pure(s + 1, len - 1));
}

#define CHECK_INT(X) static_assert(X ## _pure, "Not pure")

int main()
{
  CHECK_INT("123.0");
}
#包括
#包括
常量表达式布尔运算符“”\u pure(字符常量*s,标准::大小\u t len)
{
返回len==0||

(“0”应允许在编译时检查字符文本:

constexpr bool is_number_cont( const char* str )
{
    return !*str || ( *str >= '0' && *str <= '9' && is_number_cont( str + 1 ) );
}

constexpr bool is_number( const char* str )
{
    return *str >= '1' && *str <= '9' && is_number_cont( str + 1 );
}

int main()
{
    static_assert( is_number( "123" ), "123 failed" );
    static_assert( is_number( "0" ), "0 failed" );
    static_assert( is_number( "" ), "empty string failed" );
    static_assert( is_number( "1.23" ), "1.23 failed" );
    static_assert( is_number( "abc" ), "abc failed" );
}
constexpr bool是数字内容(const char*str)
{

return!*str | |(*str>='0'&&&&str='1'&&S[0]='0'&&S[1]='0'&&S[2]='0'&&S[3]='0'&&S[4]+1很好,我第一次看到
运算符“
递归应用:)谢谢Kerrek。确实非常优雅。不确定它是否与“0”一起失败或者输入为空,though@Chrys:否,详细信息留给您填写。我非常确定(2)中不应包含“not”:)True…条件(2)应说明“如果第一个字符为“0”,则失败”…换句话说,我们不希望接受与“001”类似的内容。这是一个很好的解决方案,但我担心“constexpr”在MSVS 2013中不受支持…(谢谢。MSVS更新的编译器确实支持constexpr。我将下载并进行进一步实验…感谢您向我介绍这个概念!
#define is_number(S) \
               S[0]>='1' && S[0]<='9' && \
    (!S[1] || (S[1]>='0' && S[1]<='9' && \
    (!S[2] || (S[2]>='0' && S[2]<='9' && \
    (!S[3] || (S[3]>='0' && S[3]<='9' && \
    (!S[4] || (S[4]>='0' && S[4]<='9' && \
     !S[5]))))))))