c++ - std::add_pointer,try_add_pointer 在可能的实现中有什么用?

标签 c++ c++11

在 cppreference add_pointer ,据说我们可以将其实现为:

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)) {};

我的问题是 try_add_pointer 有什么用? 我知道这是 SFINAE。但为什么实现需要它?

最佳答案

如果您仔细阅读有关 cppreference 的页面,您会注意到这句话

Otherwise (if T is a cv- or ref-qualified function type), provides the member typedef type which is the type T.

函数有自己的类型。通常,你会在正常代码中看到类似 int(int) 的类型。 ,即接受单个整数并返回整数的函数类型。这是参数类型 std::function期望,例如 std::function<int(int)> .

然而,函数类型集也包含与成员函数相关的奇怪之处。比如

struct foo {
  int bar(int) const;
};

int(int) constbar 的函数类型.虽然此类型存在于类型系统中,但其用途有限。

[dcl.fct]

6 A cv-qualifier-seq or a ref-qualifier shall only be part of:

  • the function type for a non-static member function,
  • the function type to which a pointer to member refers,
  • the top-level function type of a function typedef declaration or alias-declaration,
  • the type-id in the default argument of a type-parameter ([temp.param]), or
  • the type-id of a template-argument for a type-parameter ([temp.names]).

The effect of a cv-qualifier-seq in a function declarator is not the same as adding cv-qualification on top of the function type. In the latter case, the cv-qualifiers are ignored. [ Note: a function type that has a cv-qualifier-seq is not a cv-qualified type; there are no cv-qualified function types. — end note ] [ Example:

typedef void F();
struct S {
  const F f;        // OK: equivalent to: void f();
};

— end example ] The return type, the parameter-type-list, the ref-qualifier, and the cv-qualifier-seq, but not the default arguments ([dcl.fct.default]) or the exception specification ([except.spec]), are part of the function type.

所以这个特征允许你给它一个函数类型,比如 int() const , 并且它应该原封不动地返回。

那就是try_add_pointer因为正如你从上面的列表中看到的那样,没有指向这些函数的常规指针,我们将在 typename std::remove_reference<T>::type* 中得到一个替换失败。 .但感谢 SFINAE,存在后备方案。

关于c++ - std::add_pointer,try_add_pointer 在可能的实现中有什么用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60932682/

相关文章:

c++ - Visual Studio Pro 2013 中的 For 循环

c++ - 具有浮点值和转换的算术运算的错误结果 - 差异很大,我想这不是不准确值的情况 (429497)?

C#:Blowfish 加密单个双字

c++ - Valgrind 在为字符串赋值时报告内存泄漏

c++ - C++中的 'retain state'是什么意思?

c++:如何编写一个类似 std::bind 的对象来检查多余的参数?

c++ - 错误 : call of overloaded distance is ambiguous

c++ - 在类内部处理回调时必须调用非静态成员函数的引用

c++ - 线程连接问题

c++ - 更改 std::unique_ptr 的删除器