Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use static_assert to check types passed to macro

I unfortunately have several macros left over from the original version of my library that employed some pretty crazy C. In particular, I have a series of macros that expect certain types to be passed to them. Is it possible to do something along the lines of:

static_assert(decltype(retval) == bool);

And how? Are there any clever alternatives?

Yes I'm aware macros are bad. I'm aware C++ is not C, etc.

Update0

Here is some related code, and the source file. Suggestions are welcome. The original question remains the same.

like image 675
Matt Joiner Avatar asked Oct 26 '10 08:10

Matt Joiner


3 Answers

I found this to be the cleanest, using @UncleBens suggestion:

#include <type_traits>

static_assert(std::is_same<decltype(retval), bool>::value, "retval must be bool");
like image 56
Matt Joiner Avatar answered Nov 19 '22 08:11

Matt Joiner


Disclaimer: This is a bad answer, there are definitely far better solutions. Just an example :)

It is bound to be already implemented, but it's trivial to implement yourself;

template <class T1, class T2> struct CheckSameType; //no definition
template <class T> struct CheckSameType<T,T>{}; //

template <class T1, class T2>
AssertHasType(T2)
{
   CheckSameType<T1, T2> tmp; //will result in error if T1 is not T2
}

To be used like this:

AssertHasType<bool>(retval);

Alternative (suggested by GMan):

template <class T1, class T2> struct SameType
{
    enum{value = false};
}
template <class T> struct SameType<T,T>
{
    enum{value = true};
}; 

To be used like

static_assert(SameType<decltype(retval), bool>::value);
like image 28
Armen Tsirunyan Avatar answered Nov 19 '22 09:11

Armen Tsirunyan


It appears you need decltype because you've got an expression, but want to verify a type. There are already enough ways to do that now (C++03). For instance, to check a bool

inline void mustBeBool(bool) { }
template<typename T> inline void mustBeBool(T t) { & (&t); } // Takes address of rvalue (&t)

// Use:
#define DifficultMacro(B) do { mustBeBool(B); foo(B); } while (false)
like image 3
MSalters Avatar answered Nov 19 '22 10:11

MSalters