我想實現一個條件指針解引用函數。其基本思路是:C++函數模板專業化的行爲與右值引用
return is_pointer(arg) ? *arg : arg
爲了限制需要專業化的數量,我試圖用右值引用了其中arg
不是指針的情況。這是我目前的實現(std::cout
在那裏僅用於調試目的):
template< typename T >
inline typename std::enable_if< std::is_pointer<T>::value == false, T >::type deref(T&& t)
{
std::cout << std::is_pointer<T>::value << std::endl;
std::cout << typeid (T).name() << std::endl;
return t;
}
template< typename T >
inline typename std::enable_if< std::is_pointer<T>::value == true, typename std::remove_pointer<T>::type& >::type deref(T t)
{
std::cout << std::is_pointer<T>::value << std::endl;
std::cout << typeid (T).name() << std::endl;
return *t;
}
現在,我得到GCC 4.6下一個相當奇怪的行爲。第一個重載用於非指針類型和指針類型。顯然,使用指針類型時,它與第二次重載衝突。如果我註釋掉第二個和呼叫使用的第一個下面...
int q;
int *p = &q;
deref(p);
...對應的控制檯輸出爲:
0
Pi
這怎麼可能是一個非指針類型(根據std::is_pointer
)也是指針類型(根據typeid
)在相同的上下文中?由於std::is_pointer
錯誤地將p
錯誤地報告爲非指針類型,所以兩個過載之間出現衝突。此外,當我更換的第一個重載標準參考R值參考:
inline typename std::enable_if< std::is_pointer<T>::value == false, T >::type deref(T& t)
它不與第二過載了衝突......我只是不明白這是怎麼回事。順便說一句,使用第二次超載收益(如預期):
1
Pi
感謝您的幫助。
感謝您的深入解釋。當我在enable_if條件中使用remove_reference時,它的確編譯。我不完全明白你的意思: – pmjobin 2011-02-11 21:13:31