views:

87

answers:

4

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.

+1  A: 
Armen Tsirunyan
Not a bad answer/concept at all, though I don't understand `AssertHasType` and the following lines, syntactically. I'd recommend making meta-functions and a static assert utility, though, which provides two re-usable utilities that can combine to make the intended effect, rather than a custom check per condition.
GMan
Or use `is_same` from the `type_traits` header (I hope it is available with VC10).
UncleBens
A: 

Most macros can be replaced with inline functions and/or templates. As a case in point, the overly clever argument-size-checking Posix isnan macro is a template in C++0x. Oh,bad example, but you get the idea.

The main exceptions to that rule are macros that essentially implement higher level language features. For example, smarter exception handling, or covariance, or a parameterized set of declarations.

In some cases the macros that can't be reasonable expressed as inline functions or templates, can be replaced with a smarter kind of preprocessing, namely code generation. Then you have a script somewhere that generates the necessary code. For example, it's possible to do options classes in pure C++ with macros and templates, but it's hairy, and as an easier-to-grok and perhaps more maintainable alternative one might use a script that generates the requisite classes, at the cost of extra build steps and dealing with multiple languages.

Cheers & hth.,

Alf P. Steinbach
Please provide a reason when you downvote. That helps others understand what's wrong with an answer. Or alternatively, it can help others disregard the downvote.
Alf P. Steinbach
+1. Having seen the code, it becomes obvious that the actual macro's are trivially replaced by a stack-allocated object, dramatically increasing reliability and readability. These macro's are used for function call/return logging.
MSalters
+1  A: 

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)
MSalters
MSalters
@MSalters: You can do that?! Oh dear...
Matt Joiner
A: 

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

static_assert(std::is_same<decltype(retval), bool>::value, "retval must be bool");
Matt Joiner