我有一些通用代码需要对成员函数的结果运行断言。这个成员函数可能是constexpr
,也可能不是。
template<typename T>
void foo(T t) {
assert(t.member_function() == 10);
}
因为t.member_function()
可能是一个常量表达式,所以我想知道在这种情况下是否可以将其视为 a static_assert
,否则默认为 normal assert
。这可能吗?
我有一些通用代码需要对成员函数的结果运行断言。这个成员函数可能是constexpr
,也可能不是。
template<typename T>
void foo(T t) {
assert(t.member_function() == 10);
}
因为t.member_function()
可能是一个常量表达式,所以我想知道在这种情况下是否可以将其视为 a static_assert
,否则默认为 normal assert
。这可能吗?
这是一个有点疯狂的解决方案。
取消注释该Const c; foo(c);
行,您会发现它不会编译。这是编译时断言。
它需要可变长度数组,也许还有其他编译器特定的东西。我在 g++-4.6 上。
数组的大小是 0 或 -1,取决于成员函数是否返回 10。因此,如果可以在编译时计算,那么编译会意识到它是一个非可变长度数组,并且它的大小为负. 负尺寸允许它抱怨。否则,它会落入传统的断言。
请注意:在运行时断言失败后,我得到了一些运行时版本的核心转储。也许它不喜欢尝试free
负大小的数组。更新:我收到任何断言失败的核心转储,甚至int main() {assert (1==2);}
. 这是正常的吗?
#include <iostream>
#include <cassert>
using namespace std;
struct Const {
constexpr int member_function() { return 9; }
};
struct Runtime {
int member_function() { return 9; }
};
template<typename T>
void foo(T t) {
if(0) { // so it doesn't actually run any code to malloc/free the vla
int z[(t.member_function()==10)-1]; // fails at compile-time if necessary
}
assert(t.member_function()==10);
}
int main() {
//Const c; foo(c);
Runtime r; foo(r);
}