I have this code:
#ifdef _DEBUG
#define MY_VERY_SPECIAL_ASSERT(x, ...) assert(x && __VA_ARGS__)
#else
#define MY_VERY_SPECIAL_ASSERT(x, ...)
#endif
which does precisely what it's supposed to. But, in an effort to continue learning forevermore, I'm trying to abide by the constexpr
variadic template guideline from the core-cpp set.
I've tried a few permutations, but this one seems the most "correct"
#ifdef _DEBUG
template<typename T>
constexpr void MY_VERY_SPECIAL_ASSERT(T x, const std::string &msg) {
assert(x && msg);
}
#else
template<typename T>
constexpr void MY_VERY_SPECIAL_ASSERT(T x, const std::string &msg) { }
#endif
But of course, it doesn't want to compile. Specifically, there's no logical-and overload for "T" and string, which kind of makes sense. You'd think it'd just always return true, right?
Anyway, if anyone has any pointers here, I'm happy to learn more about templating. =)
CodePudding user response:
T
is a bool
, namely it is the result of evaluating the expression E1
with
static_cast<decltype (E1)> (false) != E1;
You're getting the error because std::string
has no implicit conversion to bool
.
constexpr void MY_VERY_SPECIAL_ASSERT(T x, const std::string &msg) {
// assert(x && static_cast<bool>(msg)); // won't work
assert(x && msg.empty()); // Should work. The string won't be displayed when an assertion fails, though.
}
But this wouldn't do what one could think it would, anyway.
assert(x && msg);
Will always result in the message "Assertion failed: x && msg" being displayed. You can use this instead:
assert ( false or !"message" );
#ifndef _DEBUG
# define SPECIAL_ASSERT(...) ()
#else
# define SPECIAL_ASSERT(COND, MSG) (assert(COND or! MSG))
#endif
SPECIAL_ASSERT( 1 == 0, "One isn't zero." );