如何在没有C++ 11的情况下进行编译时断言

mel*_*el- 10 c++ templates

在求职面试中,我被要求编写一个确定某个类型是否为指针的元函数.这是我提出的:

template <typename T>
struct is_pointer
{ static const bool value = false; }

template <typename T>
struct is_pointer<T *>
{ static const bool value = true; }
Run Code Online (Sandbox Code Playgroud)

然后我被要求编写一个元断言,如果我的is_pointer函数没有做正确的事情,它将在编译期间失败.

当我使用时static_assert,他明确地告诉我,我可能只使用C++ 98标准.我怎样才能做到这一点?

Dav*_*eas 9

有不同的方法,一个常见的尝试键入一个无效的类型:

#define static_assert(condition) \
        typedef char assert ## __LINE__ [((condition)?1:-1)]
Run Code Online (Sandbox Code Playgroud)

这可以在大多数任何上下文中使用,如果条件为假,它将使编译器跳闸,因为它会尝试键入一个无效类型(负数元素数组).它可以在不同的环境中使用:

// namespace level:
static_assert(sizeof(int)==4);
struct type {
   // class level:
   static_assert(sizeof(int)==4);
   void f() {
       // function level
       static_assert(sizeof(int)==4);
   }
};
Run Code Online (Sandbox Code Playgroud)

  • 这个甚至可以在纯C中使用:)但请注意,使用当前的宏,typedef将始终为`assert__LINE__`,原样; 要将`__LINE__`扩展为实际行号,您需要一个中间的"连接"宏调用:[应该将两个令牌粘贴在一起的宏应该做什么?](http://www.parashift.com/c++-faq /macros-with-token-pasting.html) (3认同)

nij*_*sen 5

在你的情况下

template <bool> struct assert;
template <> struct assert<true> {};
Run Code Online (Sandbox Code Playgroud)

会解决这个问题:

assert<!is_pointer<char>::value>();     // valid
assert<is_pointer<char *>::value>();    // valid

assert<is_pointer<char>::value>();      // compilation error:
                                        // use of incomplete class
Run Code Online (Sandbox Code Playgroud)