Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 static_assert: Parameterized error messages

In my previous question I wanted to use static_assert to restrict a template parameter to be a specific subtype. The question was answered, the code for archieving that is as follows:

template <typename T> 
struct X { 
    static_assert(std::is_base_of<Y,T>::value,"T must be derived from Y!");
};

Now, I want to make the error message more concise. I.e., I want to state which type is violating this constraint. E.g., if class A is not derived from Y and someone instanciates X<A>, then the error message should print "The type parameter must be derived from Y, but A isn't".

Is this somehow achievable with the standard library?

I see two challenges:

  • Assembling strings at compiletime without using boost::mpl
  • retrieving the name of the type with which T was instanciated. The name should be meaningful, ideally the same as used in the violating definition. I tried typeid(T).name() but it only returns the mangled name which is not acceptable. I remember that there was some kind of macro that returns the name of something, but I cannot recall that anymore.
like image 434
gexicide Avatar asked Jun 15 '12 12:06

gexicide


People also ask

What is Static_assert?

static_assert is a keyword defined in the <assert. h> header. It is available in the C11 version of C. static_assert is used to ensure that a condition is true when the code is compiled. The condition must be a constant expression.

What is the behavior if condition provided to Static_assert is evaluated as false?

If the condition is true, the static_assert declaration has no effect. If the condition is false, the assertion fails, the compiler displays the message in string_literal parameter and the compilation fails with an error.

What is the difference between assert () and Static_assert ()? Select one?

Answer: Static_assert is evaluated at compile time as against the assert () statement that is evaluated at run time. Static_assert has been incorporated in C++ from C++11 onwards. It takes the conditional expression and a message to be displayed as arguments.


1 Answers

You cannot do this. static_assert wants a string literal. You have no way to assemble the semantic identity of T and Y into the string literal.

You can hope that the compiler gives an easy to read backtrace of the template instantiation stack and gives you the value of T and Y template parameters of the enclosing class template instantiation.

Other people thought about this too, see http://comments.gmane.org/gmane.comp.compilers.clang.devel/5073 for example.

like image 184
Johannes Schaub - litb Avatar answered Oct 07 '22 01:10

Johannes Schaub - litb