【发布时间】:2011-02-11 20:36:43
【问题描述】:
我正在尝试实现条件指针取消引用功能。基本思路如下:
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
感谢您的帮助。
【问题讨论】:
标签: c++ c++11 template-specialization rvalue-reference enable-if