提供一个安全的" push()函数用于auto_ptr

时间:2011-05-17 19:37:40

标签: c++ templates auto-ptr

我想声明一个“安全”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是一些类似堆栈的容器类,我必须使用它的源代码我可以更改(就像{{1} }})。我可以假设它有一个std::stack成员函数。

  • 我不能使用push(),因为我不需要C ++ 0x编译器。

3 个答案:

答案 0 :(得分:3)

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

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 );

答案 1 :(得分:1)

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

此迭代试图提供push作为任何类的函数模板,提供可以存储T*的推送成员。目的是允许auto_ptr<T>0作为参数,但禁止其他整数值和指针。

基本技巧仍然相同:提供一个重载,使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

答案 2 :(得分:0)

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

的原因