提供“安全”的环境。与 auto_ptr 一起使用的 push() 函数

发布于 2024-11-08 16:28:30 字数 979 浏览 0 评论 0原文

我想声明一个“安全”的 push() 函数,与 auto_ptr 一起使用,如下所示:

template<class StackType,typename T>
inline void push( StackType &s, auto_ptr<T> p ) {
  s.push( p.get() );
  p.release();
}

我也希望它适用于空指针,例如:

push( my_stack, 0 ); // push a null pointer

因此,有一个专门化:

template<class StackType>
inline void push( StackType &s, int p ) {
  s.push( reinterpret_cast<typename StackType::value_type>( p ) );
} 

虽然它可以工作,但它既丑陋又允许错误的代码,例如:

push( my_stack, 1 ); // ???

编译。

如何编写 push() 的特化,使其仅接受 0 作为有效的 int 值(对于空指针)?

要求

  • StackType 是一些我必须使用的类似堆栈的容器类,但我不能使用其源代码> 更改(就像 std::stack 一样)。我可以假设它有一个 push() 成员函数。

  • 我无法使用 nullptr,因为我不需要 C++0x 编译器。

I want to declare a "safe" push() function for use with auto_ptr like this:

template<class StackType,typename T>
inline void push( StackType &s, auto_ptr<T> p ) {
  s.push( p.get() );
  p.release();
}

I also want it to work for null pointers, e.g.:

push( my_stack, 0 ); // push a null pointer

Hence, a specialization:

template<class StackType>
inline void push( StackType &s, int p ) {
  s.push( reinterpret_cast<typename StackType::value_type>( p ) );
} 

While it works, it's both ugly and allows erroneous code like:

push( my_stack, 1 ); // ???

to compile.

How can I write a specialization of push() such that it accepts only 0 as a valid int value (for the null pointer)?

Requirements

  • StackType is some stack-like container class that I must use and whose source code I can not change (just like std::stack). I can assume it has a push() member function.

  • I can not use nullptr since I can not require a C++0x compiler.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

偏闹i 2024-11-15 16:28:30

您可以按如下方式重载该函数:

template<class StackType,typename T>
inline void push( StackType &s, auto_ptr<T> p ) {
  s.push( p.get() );
  p.release();
}

template<class StackType>
inline void push( StackType &s )
{
  s.push( reinterpret_cast<typename StackType::value_type>( 0 ) );
}

然后使用它:

push( my_stack );
push( my_stack, auto_ptr_var );

You could overload the function as follows:

template<class StackType,typename T>
inline void push( StackType &s, auto_ptr<T> p ) {
  s.push( p.get() );
  p.release();
}

template<class StackType>
inline void push( StackType &s )
{
  s.push( reinterpret_cast<typename StackType::value_type>( 0 ) );
}

then use it:

push( my_stack );
push( my_stack, auto_ptr_var );
年华零落成诗 2024-11-15 16:28:30

编辑:第二次迭代。 (第一个假设某个特定堆栈类的 push 方法将被重载。)

此迭代旨在提供 push 作为任何提供推送的类的函数模板接受的成员可以存储T*。目的是允许 auto_ptr0 作为参数,但不允许使用其他整数值和指针。

基本技巧仍然是相同的:提供一个重载,使得 push(s, 0) 实际上将 0 解释为指向成员的空指针。

class X;

template<typename StackType, typename T>
void push(StackType& s, std::auto_ptr<T> p);

template<typename ST>
void push(ST&, int (X::*));

class X {
  private:
    int m;
    X(); // unimplemented
    X(const X&); // unimplemented
    X& operator=(const X&); // unimplemented
    ~X(); // unimplemented

   template<typename ST>
   friend
   void push(ST&, int (X::*));
};

template<typename StackType, typename T>
void push(StackType& s, std::auto_ptr<T> p) {
    s.push(p.get());
    p.release();
}

template<typename StackType>
void push(StackType& s, int (X::*)) {
    s.push(0);
}

测试:

std::stack<int*> s;
push(s, std::auto_ptr(new int(1))); // works
push(s, 0);  // works
push(s, 1);  // errors out: no matching function

EDIT: second iteration. (The first assumed that the push method of some particular stack class was to be overloaded.)

This iteration instead seeks to provide push as a function template for any class providing a push member that takes can store T*. The intent is to allow auto_ptr<T> and 0 as arguments, but to disallow other integral values and pointers.

The basic trick is still the same: provide an overload such that push(s, 0) actually interprets 0 as a null pointer to member.

class X;

template<typename StackType, typename T>
void push(StackType& s, std::auto_ptr<T> p);

template<typename ST>
void push(ST&, int (X::*));

class X {
  private:
    int m;
    X(); // unimplemented
    X(const X&); // unimplemented
    X& operator=(const X&); // unimplemented
    ~X(); // unimplemented

   template<typename ST>
   friend
   void push(ST&, int (X::*));
};

template<typename StackType, typename T>
void push(StackType& s, std::auto_ptr<T> p) {
    s.push(p.get());
    p.release();
}

template<typename StackType>
void push(StackType& s, int (X::*)) {
    s.push(0);
}

Test:

std::stack<int*> s;
push(s, std::auto_ptr(new int(1))); // works
push(s, 0);  // works
push(s, 1);  // errors out: no matching function
陌生 2024-11-15 16:28:30

您需要一个特定的空指针类型来处理这种情况。这就是 C++11 引入 nullptr 的原因。

You need a specific null pointer type to handle this case. This is why C++11 brings in nullptr.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文