I have some generic code that needs to run an assertion over the result of a member function. This member function may be constexpr
, or it may not be.
template<typename T>
void foo(T t) {
assert(t.member_function() == 10);
}
Because t.member_function()
might be a constant expression, I'm wondering if it's possible to be treated as a static_assert
in such cases, but otherwise default to a normal assert
. Is this possible?
This is a slightly crazy solution.
Uncomment the Const c; foo(c);
line and you'll see that it won't compile. This is the compile-time assert.
It requires variable length arrays, and maybe other compiler specific stuff. I'm on g++-4.6.
The size of the array is either 0 or -1, depending on whether the member function returns 10. So if this can be computed at compile-time, then the compile realizes it's a non-variable length array, and that it has negative size. The negative size allows it to complain. Otherwise, it falls through to a conventional assert.
Please note: I'm getting some core dump with the Runtime version just after the runtime assertion fails. Maybe it doesn't like trying to free
an array with negative size. Update: I'm getting core dumps with any assertion failure, even int main() {assert (1==2);}
. Is this normal?
#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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With