The answer to the first question: "No." The argument that you pass to the template is called the so-called "non-type template argument". According to the standard, such arguments should be:
constant expressions, addresses of functions or objects with external communication, or addresses of static members of a class.
An expression like true && "err msg" strictly speaking cannot be determined at compile time. Therefore, it can be used with runtime statements, but not at compile time. g ++ demonstrates non-standard behavior here.
As an answer to the second question, I propose the following template:
#define STATIC_ASSERT(e,m) extern char (*__static_assert_failed(void)) [ 1 - 2*!(e) ]
__static_assert_failed here is a pointer to an external function that returns an array of characters. The array has a size of 1 - 2*!(e) , which becomes negative if e is false, causing a compile-time error.
source share