C++ compile time checker using templates
I am having following code which is taken from modern C++ design. While i am using it i am getting compiation error i think invalid sizeof opeara开发者_StackOverflownd. Can any one point out what is the problem. Thanks!
template<bool>
struct CompileTimeChecker {
CompileTimeChecker(...);
};
template<>
struct CompileTimeChecker<false> {
};
#define STATIC_CHECK(expr, msg) \
{\
class ERROR_##msg {}; \
(void)sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg())));\
}
template <class To, class From>
To safe_reinterpret_cast(From from) {
STATIC_CHECK(sizeof(From) <= sizeof(To), Destination_Type_Too_Narrow);
return reinterpret_cast<To>(from);
}
int main(void)
{
int a[20];
void* somePointer = a;
char c = safe_reinterpret_cast<int>(somePointer);
}
Error:
d:\technical\c++study\readparsing\readparsing\addressconv.cpp(29) : error C2066: cast to function type is illegal 1> d:\technical\c++study\readparsing\readparsing\addressconv.cpp(37) : see reference to function template instantiation 'To safe_reinterpret_cast(From)' being compiled 1> with 1> [ 1> To=int, 1> From=void * 1> ] 1>d:\technical\c++study\readparsing\readparsing\addressconv.cpp(29) : error C2070: 'CompileTimeChecker<__formal> (safe_reinterpret_cast::ERROR_Destination_Type_Too_Narrow (__cdecl *)(void))': illegal sizeof operand 1> with 1> [ 1> __formal=true 1> ]
Yet another strike for the most vexing parse...
sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg()))
Is the same as
class Foo {};
class Bar {};
sizeof(Foo((Var()));
and as Foo(Var) can be interpreted either as a type (function taking a (function without an argument an returning a Var) and returning a Foo), it is so.
Like AProgrammer pointed out, the (void)sizeof isn't getting swallowed by the compiler. I suggest removing the parentheses from the sizeof, like this:
(void)sizeof CompileTimeChecker<(expr) != 0>((ERROR_##msg()));\
That seems to make g++ accept it, and interpret it the way it was probably meant to.
If that (void)sizeof keeps giving you trouble, you can get the static checking functionality without it too, for example by initializing a CompileTimeChecker variable:
CompileTimeChecker<(expr) != 0> a((ERROR_##msg()));\
精彩评论