C ++使用模板编译时间检查器

时间:2011-02-27 10:34:11

标签: c++ most-vexing-parse

我有以下代码,它取自现代C ++设计。虽然我正在使用它我得到compiation错误我认为无效sizeal opearand。任何人都可以指出问题是什么。谢谢!

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);
}

错误:

  

d:\ technical \ c ++ study \ readparsing \ readparsing \ addressconv.cpp(29):错误C2066:强制转换为函数类型是非法的   1 GT; d:\ technical \ c ++ study \ readparsing \ readparsing \ addressconv.cpp(37):参见函数模板实例化'to safe_reinterpret_cast(From)'被编译   1 GT;同   1 GT; [   1 GT;为了= INT,   1 GT; From = void *   1 GT; ]   1&gt; d:\ technical \ c ++ study \ readparsing \ readparsing \ addressconv.cpp(29):错误C2070:'CompileTimeChecker&lt; __ formal&gt; (safe_reinterpret_cast :: ERROR_Destination_Type_Too_Narrow(__ cdecl *)(void))':非法sizeof操作数   1 GT;同   1 GT; [   1 GT; __formal =真   1 GT; ]

2 个答案:

答案 0 :(得分:4)

对于最令人烦恼的解析又一次罢工......

sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg()))

相同
class Foo {};
class Bar {};
sizeof(Foo((Var()));

并且因为Foo(Var)可以解释为一个类型(函数采用(没有参数的函数返回Var)并返回一个Foo),它就是这样。

答案 1 :(得分:1)

像AProgrammer所指出的那样,(void)sizeof不会被编译器吞噬。我建议从sizeof中删除括号,如下所示:

(void)sizeof CompileTimeChecker<(expr) != 0>((ERROR_##msg()));\

这似乎使g ++接受它,并按照它可能的意图解释它。

如果那个(void)sizeof一直给你带来麻烦,你可以在没有它的情况下获得静态检查功能,例如通过初始化CompileTimeChecker变量:

CompileTimeChecker<(expr) != 0> a((ERROR_##msg()));\