std :: add_pointer, lo que la try_add_pointer en la posible aplicación?

user1617424:

En cppreference add_pointer , se dice que podemos implementarlo como:

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

Mi pregunta es ¿cuál es la try_add_pointerde? Sé que es SFINAE. Pero ¿por qué la aplicación lo necesitan aquí?

Narrador - Unslander Mónica:

Si usted lee sobre la página en cppreference, se dará cuenta de esta frase

En caso contrario (si T es un CV- o tipo de función ref-cualificada), proporciona el miembro typedef tipo que es el tipo T.

Función tienen sus propios tipos. Normalmente, lo que se verá en el código Sane tipos les gusta int(int), es decir, el tipo de una función que toma un solo entero y devuelve un número entero. Este es el tipo de argumento std::functionEspera, por ejemplo std::function<int(int)>.

Sin embargo, el conjunto de tipos de función también contiene rarezas que se relacionan con las funciones miembro. Por ejemplo

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

int(int) constes el tipo de función de bar. Si bien existe este tipo en el sistema de tipos, que está limitado en sus usos.

[Dcl.fct]

6 Un CV-calificador-seq o un ref-calificador sólo serán parte de:

  • el tipo de función de una función miembro no estática,
  • el tipo de función a la que se refiere un puntero a miembro,
  • el tipo de función de nivel superior de una declaración typedef función o alias-declaración,
  • el tipo-id en el argumento predeterminado de un parámetro de tipo ([temp.param]), o
  • el tipo-id de una plantilla-argumento para un tipo de parámetro ([temp.names]).

El efecto de un cv-calificador-seq en un declarador función no es la misma que la adición de cv-calificación en la parte superior del tipo de función. En este último caso, la CV-calificadores se ignoran. [Nota: un tipo de función que tiene un cv-calificador-ss no es un tipo cv-calificado; no hay tipos de función CV-calificado. - nota final] [Ejemplo:

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

- ejemplo final] El tipo de retorno, la de tipo-lista de parámetros, la ref-calificador, y la CV-calificador-seq, pero no los argumentos por defecto ([dcl.fct.default]) o la especificación de excepción ([excepto. spec]), son parte del tipo de función.

Por lo que el rasgo le permite alimentar un tipo de función como int() const, y se espera que devolverlo sin cambios.

Ahí es donde try_add_pointerentra. Dado que como se puede ver en la lista anterior, no hay punteros regulares a este tipo de funciones, obtendremos un fallo en sustitución typename std::remove_reference<T>::type*. Pero gracias a SFINAE, existe un retroceso.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=369635&siteId=1
Recomendado
Clasificación