2011-05-17 28 views
2

我想聲明中使用的「安全」 push()功能與auto_ptr這樣的:提供了一個「安全的」推()函數的使用與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編譯器。

+0

你會知道在編譯時,該指針爲空?即你會有這樣的代碼嗎?:'char * ptr = 0; push(my_stack,ptr);' – 2011-05-18 00:17:51

+0

@Aaron:我會在編譯時知道指針是空的,即,是字面值0. – 2011-05-18 00:28:52

+0

我還沒有一個好的答案,但是澄清它是一個字面'0'是有用的。你會被允許製作你自己的'nullptr'類型的克隆,並且要求用戶傳入一個這種類型的實例嗎? 'push(my_stack,my_null)'還有一個問題:假設它必須是一個文字'0',你會被允許將'push'定義爲一個宏嗎? – 2011-05-18 13:14:15

回答

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

我們沒有給出's.push'的詳細信息,但我認爲's.push(0)'是想要的而不是'reinterpret_cast'的東西。 (例如在問題中提到空指針)。 – 2011-05-17 19:56:22

0

你需要一個特定的空指針類型來處理這種情況。這就是C++ 11帶來nullptr的原因。

+0

我知道nullptr,但代碼不需要C++ 11編譯器。 – 2011-05-17 20:16:29

1

編輯:第二次迭代。 (第一種假設某些特定堆棧類的push方法將被重載。)

本次迭代改爲將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 
+0

旁邊的表單過大,你的實現並不能解決問題。你的行「stk.push_back(p.release());」是不是例外安全的:如果push_back()拋出,p將會泄漏。在推動成功之後,整個問題不會被釋放。 – 2011-05-17 21:23:23

+0

我並不是想讓它變得異常安全。我試圖告訴你如何重載一個函數,以便它接受NULL作爲唯一的裸指針。唯一的矯枉過正是我想要一個完全獨立的例子。 – Lambdageek 2011-05-17 21:25:57

+0

好吧,爲了公平起見,我應該說「接受NULL作爲'S' **」非「朋友」唯一的裸指針**「 – Lambdageek 2011-05-17 21:28:11

相關問題