2

我有这个队列类,实际上,有几个遇到相同的问题 - 如果使用具有冗长复制 ctor 的类型编译性能会很差 - 队列在推送/弹出期间被锁定,并且锁定的时间越长,争执的机会更大。如果某些开发人员尝试使用 10MB 缓冲区类(而不是指向它的指针)编译该类,则该类无法编译将很有用。

似乎没有简单的方法可以将模板参数限制为基类或任何其他类型。

如果参数不是指向类实例的指针,是否有一些我可以使用的 bodge 以便我的类无法编译?

4

4 回答 4

6

您可以通过多种方式做到这一点。正如另一个答案指出的那样,您可以使用 static_assert (最好来自 C++11/Boost,尽管您可以自己滚动),尽管我建议检查它是否实际上是一个指针,而不仅仅是依赖于大小。您可以自己滚动或使用现有特征C++11 中也可用),具体取决于您使用的系统:

template <typename T>
struct is_pointer {
  enum { value = 0 };
};

template <typename T>
struct is_pointer<T*> {
  enum { value = 1 };
};

template <typename T>
struct container {
  static_assert(is_pointer<T>::value, "T must be a pointer");
  void push(const T&);
  T pop();
};

struct foo {};

int main() {
  container<foo*> good;
  container<foo> fail;
}

但这提出了一个更大的问题。如果您的要求是您只指向事物,为什么不这样解释模板参数呢?例如制作你的容器:

template <typename T>
struct container {
  void push(const T*);
  T *pop();
};

而不是让人们首先指定非指针类型?

最后,如果您不想走 static_assert 道路,您可以只为指针类型专门化容器,而不为非指针实现它,例如:

template <typename T>
struct container;

template <typename T>
struct container<T*> {
  void push(const T*);
  T *pop();
};

struct foo {};

int main() {
  container<foo*> good;
  container<foo> fail;
}

这仍然需要显式地将类型设为指针,仍然会导致非指针类型的编译时失败,但不需要 static_assert 或确定类型是否为指针的方法。

于 2012-04-13T14:18:33.817 回答
2

“如果参数不是指向类实例的指针,是否有一些我可以使用的 bodge 以便我的类无法编译?”

不是boge,而是:

template<class T>
class MyContainer
{
public:
    void AllMemberFunctions( T* in ){}
    void OnlyAcceptTStars( T* in ){}

};

用户定义所持有的类型,您的函数只接受或处理指向该类型的指针。

(或者做 STL 所做的,假设用户有一些智慧,然后忘记这个问题。)

于 2012-04-13T14:24:00.677 回答
0

使用静态断言的变体(对于许多可能的实现,只需 google)。类似的东西BOOST_STATIC_ASSERT(sizeof(T) <= sizeof(void*))应该可以解决问题。

于 2012-04-13T14:07:26.477 回答
0

是的,您可以使用 static_assert 来完成。例如,

template<int N>
class Queue
{
static_assert(N < size, "N < size violated");
...
};
于 2012-04-13T14:09:51.870 回答