Home > Back-end >  Variadic template calling assert()
Variadic template calling assert()

Time:12-13

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." );
  • Related