10

在一次工作面试中,我被要求编写一个元函数来确定一个类型是否是一个指针。这是我介绍的:

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

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

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

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

4

3 回答 3

9

有不同的方法,一种常见的方法是尝试对无效类型进行 typedef:

#define static_assert(condition) \
        typedef char assert ## __LINE__ [((condition)?1:-1)]

这可以在大多数情况下使用,如果条件为假,编译器会跳闸,因为它会尝试 typedef 无效类型(负数元素的数组)。它可以在不同的上下文中使用:

// 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);
   }
};
于 2013-07-23T17:32:15.060 回答
5

在你的情况下

template <bool> struct assert;
template <> struct assert<true> {};

本来可以解决问题的:

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

assert<is_pointer<char>::value>();      // compilation error:
                                        // use of incomplete class
于 2013-07-23T17:26:05.617 回答
3

我会用BOOST_STATIC_ASSERT. 您可以查看代码:boost/static_assert.hpp

这是一个非常简化的版本,只是为了给您一个想法:

#define JOIN(X, Y) DO_JOIN(X, Y)
#define DO_JOIN(X, Y) X ## Y

template<bool cond>
struct Static_assert_helper;  // incomplete type

template<>
struct Static_assert_helper<true> {
    typedef int Type;
};

#define STATIC_ASSERT(cond) \
    typedef Static_assert_helper<(cond)>::Type JOIN(Static_assert_typedef_, __LINE__)

它可以在许多地方使用(请参阅文档以获取示例)。

(Boost 的实现更完整,例如 asizeof和一个中间结构,以提供更好的错误消息并在各种编译器上可移植。)

于 2013-07-24T10:06:33.473 回答