C++ 在编译时表达式未知时传递的静态断言
我想实现与c++17单参数C++ 在编译时表达式未知时传递的静态断言,c++,C++,我想实现与c++17单参数static\u assert略有不同的myu static\u assert:如果编译时myu static\u assert中的条件未知,它应该通过 下面示例中的第二个my_static_assert应该通过,但是如果我使用static_assert它将失败 #include <iostream> int x, y; constexpr int f1() { return 0; } constexpr int f2() { return 0; } in
static\u assert
略有不同的myu static\u assert
:如果编译时myu static\u assert
中的条件未知,它应该通过
下面示例中的第二个my_static_assert
应该通过,但是如果我使用static_assert
它将失败
#include <iostream>
int x, y;
constexpr int f1() { return 0; }
constexpr int f2() { return 0; }
int f3() { return x; }
int f4() { return y; }
constexpr int sum(int a, int b) { return a + b; }
int main() {
std::cin >> x >> y;
// it should fail
my_static_assert(sum(sum(f1(), f2()), sum(f1(), f1())) != 0);
// it should pass
my_static_assert(sum(sum(f1(), f2()), sum(f4(), sum(f3(), f1()))) != 0);
}
#包括
int x,y;
constexpr int f1(){return 0;}
constexpr int f2(){return 0;}
int f3(){return x;}
int f4(){return y;}
constexpr int sum(int a,int b){返回a+b;}
int main(){
标准:cin>>x>>y;
//它应该失败
我的静态断言(sum(sum(f1(),f2()),sum(f1(),f1())!=0);
//它应该通过
我的静态断言(sum(sum(f1(),f2()),sum(f4(),sum(f3(),f1())!=0);
}
如果您想知道为什么会出现这个问题:
我正在使用叶函数f1、f2、f3、f4和表达式节点上的操作构建表达式:sum、mul、div、sub。编译时已知的叶函数包含始终为0的值
我正在尝试检查我的表达式是否至少包含一个编译时未知的元素。如果您愿意提交给带有GNU扩展的编译器,这是可能的。因此,请注意 它需要两个重载和一个辅助宏:
template<std::size_t N>
constexpr void assert_helpr(int(&)[N]) = delete;
void assert_helpr(...) {}
#define my_static_assert(...) do { \
__extension__ int _tmp [(__VA_ARGS__) + 1]; \
assert_helpr(_tmp); \
} while(0)
模板
constexpr void assert_helpr(int(&)[N])=delete;
void assert_helpr(…){}
#定义我的静态断言(…)do{\
__扩展名uuu int u tmp[(uu VA_ARGS_uuu)+1]\
assert_helpr(_tmp)\
}而(0)
其工作原理如下:
非常友好地分享了基于此方法的解决方案 下面是解决此问题的一组代码:
template<std::size_t N>
constexpr std::false_type assert_helpr(int(&)[N]);
constexpr std::true_type assert_helpr(...);
#define my_static_assert(...) do { \
__extension__ int _tmp[(__VA_ARGS__) + 1]; \
static_assert(decltype(assert_helpr(_tmp)){}, #__VA_ARGS__); \
} while(0)
模板
constexpr std::false_type assert_helpr(int(&)[N]);
constexpr std::true_type assert_helpr(…);
#定义我的静态断言(…)do{\
__扩展名uuu int u tmp[(uu VA_ARGS_uuu)+1]\
静态断言(decltype(assert_helpr(_tmp)){}、#uu VA_ARGS_uu)\
}而(0)
重载的用法相同,除了这次我们通过decltype
从调用中获取一个实际的结果类型,并继续从中创建一个真正的编译时布尔常量
这允许直接使用
static\u assert
,作为一个很好的特性,我们可以将字符串化标记传递给它,以获得失败表达式的错误指示。我认为这是不可能的:(中似乎有几个选项。但不确定这是否应该是一个重复。这类似于is_constexpr
。有,但它得出结论,没有符合标准的方法来实现这一点。有一个版本深受此版本的启发,它使用了静态断言
,因此有一条消息:。它也有一些问题es(“代码>常量”和“编译时常量”之间的区别”)@Artyer-一点也不坏!