C++模板中函数模板特化的行为

C++模板中函数模板特化的行为,c++,c++11,template-specialization,rvalue-reference,enable-if,C++,C++11,Template Specialization,Rvalue Reference,Enable If,我正在尝试实现一个条件指针解引用函数。基本思路如下: 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 de

我正在尝试实现一个条件指针解引用函数。基本思路如下:

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;
}
。。。相应的控制台输出为:

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)

谢谢您的帮助。

在您的第一个重载中,T被推断为int*&。尝试在第一个重载中使用remove_reference::键入enable_if-testing和输出。

在第一个重载中,T被推断为int*&。在第一个重载中尝试使用remove_reference::键入enable_if-testing和输出。

据我所知

template <T>
void foo(T&&)
这意味着,如果T是左值,它将被推导为引用T=int*&在您的情况下,在int*&&&的引用折叠后产生一个常规左值引用int*&。如果不是这样,这个语法将捕获任何内容作为右值引用。然而,关键是将左值绑定到左值引用,将右值绑定到右值引用

而且is_指针不是真的。因此,您可以尝试应用删除引用。

据我所知

template <T>
void foo(T&&)
这意味着,如果T是左值,它将被推导为引用T=int*&在您的情况下,在int*&&&的引用折叠后产生一个常规左值引用int*&。如果不是这样,这个语法将捕获任何内容作为右值引用。然而,关键是将左值绑定到左值引用,将右值绑定到右值引用


而且is_指针不是真的。因此,您可以尝试应用remove_reference。

感谢您的深入解释。当我在enable_if条件中使用remove_引用时,它确实会编译。我不完全明白你的意思:谢谢你的深入解释。当我在enable_if条件中使用remove_引用时,它确实会编译。我不完全明白你的意思:
template <T>
void foo(T&&)