我想声明一个“安全”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编译器。
答案 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
。