我想实现一个条件指针解引用函数。其基本思路是: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