Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否引发非指针模板类的异常?_C++_Templates - Fatal编程技术网

C++ 是否引发非指针模板类的异常?

C++ 是否引发非指针模板类的异常?,c++,templates,C++,Templates,我有一个队列类,实际上,有几个队列类遇到了相同的问题-如果使用具有较长副本的类型编译,性能会很差-队列在push/pop期间被锁定,锁定的时间越长,争用的可能性越大。如果某个开发人员试图使用10MB缓冲区类(而不是指向它的指针)编译该类,那么该类将不会编译,这将非常有用 似乎没有简单的方法将模板参数限制为基类或任何其他类型 如果参数不是指向类实例的指针,我是否可以使用一些bodge使我的类不会编译 使用static assert的变体(对于许多可能的实现,只需使用google)。类似于BOOST

我有一个队列类,实际上,有几个队列类遇到了相同的问题-如果使用具有较长副本的类型编译,性能会很差-队列在push/pop期间被锁定,锁定的时间越长,争用的可能性越大。如果某个开发人员试图使用10MB缓冲区类(而不是指向它的指针)编译该类,那么该类将不会编译,这将非常有用

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


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

使用static assert的变体(对于许多可能的实现,只需使用google)。类似于
BOOST\u STATIC\u ASSERT(sizeof(T)是的,您可以使用STATIC\u ASSERT来实现

template<int N>
class Queue
{
static_assert(N < size, "N < size violated");
...
};
模板
类队列
{
静态_断言(N
您可以通过几种方式来实现这一点。正如另一个答案所指出的,您可以使用静态断言(最好是从C++11/Boost中实现,尽管您可以),但我建议您检查它是否实际上是一个指针,而不仅仅是取决于大小。您可以滚动自己的或使用(也可用),具体取决于您使用的系统:

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;
}
模板
结构是指针{
枚举{value=0};
};
模板
结构是指针{
枚举{值=1};
};
模板
结构容器{
静态断言(是指针::值,“T必须是指针”);
无效推力(常数T&);
T pop();
};
结构foo{};
int main(){
集装箱货物;
容器失效;
}
但这引出了一个更大的问题。如果您的要求是只指向对象,那么为什么不从开始就这样解释模板参数?例如,制作容器:

template <typename T>
struct container {
  void push(const T*);
  T *pop();
};
模板
结构容器{
无效推力(常数T*);
T*pop();
};
而不是允许人们首先指定非指针类型

最后,如果您不想走静态断言的道路,您可以只将容器专门用于指针类型,而不将其用于非指针,例如:

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;
}
模板
结构容器;
模板
结构容器{
无效推力(常数T*);
T*pop();
};
结构foo{};
int main(){
集装箱货物;
容器失效;
}
这仍然需要显式地将类型设置为指针,仍然会导致非指针类型的编译时失败,但不需要静态断言或确定类型是否为指针的方法。

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

不是一个预兆,但是:

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

};
模板
类霉菌容器
{
公众:
void AllMemberFunctions(T*in){}
仅无效接受星号(T*in){}
};
用户定义所持有的类型,而您的函数只接受或处理指向该类型的指针


(或者像STL那样,假设用户有一些智能,忘记这个问题。)

仅仅因为T很小并不意味着它有一个简单的复制构造函数。嗯,你是对的。但是也有一些特性帮助器类来确定类型是否是(比如)基元类型。因此可以用它来代替测试的大小。那么,你可能应该支持移动构造函数。移动一个10 MB的缓冲区类不需要花费太多这是一个老问题,但在C++11中,他们添加了std::is_指针