为什么在 std::add_pointer_t 中需要 SFINAE?
Why do you need SFINAE in `std::add_pointer_t`?
我最近一直在研究标准库,因为我需要为没有 stdlib 实现的系统实现它的一个子集(主要是模板内容)。
我在 cppreference:
中遇到了这个“可能的实现”
namespace detail {
template <class T>
struct type_identity { using type = T; }; // or use std::type_identity (since C++20)
template <class T>
auto try_add_pointer(int) -> type_identity<typename std::remove_reference<T>::type*>;
template <class T>
auto try_add_pointer(...) -> type_identity<T>;
} // namespace detail
template <class T>
struct add_pointer : decltype(detail::try_add_pointer<T>(0)) {};
而且我一直想知道为什么您需要 SFINAE。这不是吗:
template< class T >
struct add_pointer {
typedef typename std::remove_reference<T>::type* type;
};
够了吗?哪个实例化采用第二种情况 try_add_pointer
?我试着想了想,但想不出这样的情况。
我不确定这是否是唯一的坏情况,但是您的实现对于所谓的“可恶的函数类型”失败了:
add_pointer<void() const>::type // hard error instead of void() const
我最近一直在研究标准库,因为我需要为没有 stdlib 实现的系统实现它的一个子集(主要是模板内容)。
我在 cppreference:
中遇到了这个“可能的实现”namespace detail {
template <class T>
struct type_identity { using type = T; }; // or use std::type_identity (since C++20)
template <class T>
auto try_add_pointer(int) -> type_identity<typename std::remove_reference<T>::type*>;
template <class T>
auto try_add_pointer(...) -> type_identity<T>;
} // namespace detail
template <class T>
struct add_pointer : decltype(detail::try_add_pointer<T>(0)) {};
而且我一直想知道为什么您需要 SFINAE。这不是吗:
template< class T >
struct add_pointer {
typedef typename std::remove_reference<T>::type* type;
};
够了吗?哪个实例化采用第二种情况 try_add_pointer
?我试着想了想,但想不出这样的情况。
我不确定这是否是唯一的坏情况,但是您的实现对于所谓的“可恶的函数类型”失败了:
add_pointer<void() const>::type // hard error instead of void() const