2013-04-02 60 views
4

在主函數中調用push方法時使用push方法。但是,即使主函數中的參數是指針,它仍然使用函數void Push(const DATA_TYPE& newValue)重載函數以接受模板指針變量

它不應該使用另一個,因爲那是接受指針的那個?如果在第二個函數中有參數,如果有指針變量,我該如何改變參數?

template<typename DATA_TYPE> 
void Push(const DATA_TYPE& newValue) 
{ 
    //do stuff 
} 

template<typename DATA_TYPE> 
void Push(const DATA_TYPE *newValue) 
{ 
    //do stuff 
} 
+0

看看http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/ Stephan-T-Lavavej-Core-Cpp-3-of-n一切都很好解釋。 –

回答

4

你的問題是與常量性。

的問題是,當你調用Push(p)與非const對象的指針,P * p第一個版本的作品完全設置DATA_TYPE = P*時,給人的Push(const P* &)函數簽名。相比之下,與DATA_TYPE = P第二個版本需要增加const的類型簽名得到Push(const P*)。這意味着選擇了第一個版本,而不是第二個版本,因爲它完全匹配。

下面是一個例子來闡明這是怎麼回事:

下面是一個例子:

#include <iostream> 

class Foo 
{ 
    public: 
    template<typename DT> 
    void Push(const DT& newValue) 
    { 
     std::cout<<"In const DT& version"<<std::endl; 
    } 

    template<typename DT> 
    void Push(const DT *newValue) 
    { 
     std::cout<<"In const DT* version"<<std::endl; 
    } 
}; 

int main() 
{ 
    Foo f; 

    int i=7; 

    // Since i is not const we pickup the wrong version 
    f.Push(i); // const DT& (DT = int) 
    f.Push(&i); // const DT& (DT = int*) 

    // Here's using a const pointer to show it does the right things 
    const int * const_i_ptr = &i; 
    f.Push(const_i_ptr); // const DT* (DT = int); 

    // Now using a const object everything behaves as expected 
    const int i_const = 7; 
    f.Push(i_const); // const DT& (DT = int); 
    f.Push(&i_const); // const DT* (DT = int); 
} 
+0

您可能已經澄清說,這意味着參考版本提供了完全匹配,但是他的指針版本仍然需要從「非const」指向「const」指針的類型轉換,因此參考版本更匹配。 – Keith

+0

@Keith我同意,希望我現在已經解決了這個問題。 –

0

我測試過這個程序

#include <iostream> 

template <typename T> 
void push(T&) 
{ 
    std::cout << "By ref" << std::endl; 
} 

template <typename T> 
void push(T*) 
{ 
    std::cout << "By ptr" << std::endl; 
} 

int main() 
{ 
    int x = 0; 
    push(x); 
    push(&x); 
    return 0; 
} 

它輸出

By ref 
By ptr 
+1

這裏的區別是在'模板 無效的push(T *)'是一個模板,其中'無效推送(常量DATA_TYPE * NEWVALUE)'是不是。我不明白這與這個問題有什麼關係。 – Mankarse

+0

你用const試過嗎? –

+0

你缺少'const'。 '&x'是一個右值,不能綁定到'non-const' ref。 –

0

這是因爲const DATA_TYPE& newValue將匹配相當多的東西,在你的情況下,它作爲參考指針const DATA_TYPE*& newValue匹配。嘗試使用std::remove_pointerdescribed here - 從我的頭頂,我會寫:

template<typename DATA_TYPE> 
void Push(const typename std::remove_pointer<DATA_TYPE>::type& newValue) 
{ 
    //do stuff 
} 

template<typename DATA_TYPE> 
void Push(const DATA_TYPE *newValue) 
{ 
    //do stuff 
} 

Nothe然而,寫作模板匹配const T&與其他模板重載沿通常會導致const T&搶每一個電話,所以你應該避免做這樣。

編輯:

我以前的代碼是不正確的,它必須是有點複雜:

#include <iostream> 
#include <type_traits> 

template<typename DATA_TYPE, bool is_pointer> 
struct helper; 

template<typename DATA_TYPE> 
struct helper<DATA_TYPE, true>{ 
    static void f(const typename std::remove_pointer<DATA_TYPE>::type*){ 
     std::cout << "Pointer" << std::endl; 
    } 
}; 

template<typename DATA_TYPE> 
struct helper<DATA_TYPE, false>{ 
    static void f(const DATA_TYPE&){ 
     std::cout << "Non-pointer" << std::endl; 
    } 
}; 

template<typename DATA_TYPE> 
void Push(const DATA_TYPE& newValue) 
{ 
    helper<DATA_TYPE, std::is_pointer<DATA_TYPE>::value >::f(newValue); 
} 

int main() 
{ 
    int i=0; 
    Push(i); 
    Push(&i); 
    return 0; 
} 

這工作正常,並沒有強制呼叫者使用適當的常量-ness,雖然我承認它並不像我以前的解決方案那樣光鮮;)

+0

看來你不能這樣做論證類型演繹:http://ideone.com/Ift1s0 –

+0

@MichaelAnderson請參閱我的編輯... –

+0

還沒有嘗試過,但看起來更有希望。 –