首页 > 解决方案 > 为什么在 `std::add_pointer_t` 中需要 SFINAE?

问题描述

我最近一直在研究标准库,因为我需要为一个没有 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?我试着去想它,但想不出任何这样的情况。

标签: c++template-meta-programmingsfinae

解决方案


我不确定这是否是唯一不好的情况,但是对于所谓的“可恶函数类型”,您的实现失败了:

add_pointer<void() const>::type // hard error instead of void() const

推荐阅读