Me pregunto si si pruebo a algún miembro de una clase y el miembro es privado, ¿qué responderá sfinae? ¿Se equivocará o dirá que está bien o se equivocará de la misma manera?¿Puede SFINAE detectar violaciones de acceso privado?
Respuesta
Sí.
EDIT: C++ 11 cotización estándar de §14.8.2 [temp.deduct]
8/ Si un cambio da como resultado un tipo o expresión no válida, el tipo de deducción falla . Un tipo o expresión inválida es aquella que estaría mal formada si se escribiera utilizando los argumentos sustituidos. [Nota: la verificación de acceso se realiza como parte del proceso de sustitución. nota -fin]
Esto me sugiere que private
puede desencadenar un error SFINAE. Leyendo en:
Solo los tipos y expresiones no válidos en el contexto inmediato del tipo de función y sus tipos de parámetros de plantilla pueden dar como resultado un error de deducción. [Nota: la evaluación de los tipos y expresiones sustituidos puede producir efectos secundarios tales como la instanciación de especializaciones de plantilla de clase y/o especializaciones de plantilla de función, la generación de funciones implícitamente definidas, etc. Tales efectos secundarios no están en el “contexto inmediato” y puede resultar en el programa fue la nota mala formed.-final]
el "contexto inmediato" no es tan claro para mí ... pero no contradice mi punto :)
final de EDIT
Por lo tanto, me parece que va a error a cabo de una manera SFINAE, esto se ve confirmado por este extracto de Clang:
// clang/Basic/DiagnosticIDs.h:185-209
/// \brief Enumeration describing how the the emission of a diagnostic should
/// be treated when it occurs during C++ template argument deduction.
enum SFINAEResponse {
/// \brief The diagnostic should not be reported, but it should cause
/// template argument deduction to fail.
///
/// The vast majority of errors that occur during template argument
/// deduction fall into this category.
SFINAE_SubstitutionFailure,
/// \brief The diagnostic should be suppressed entirely.
///
/// Warnings generally fall into this category.
SFINAE_Suppress,
/// \brief The diagnostic should be reported.
///
/// The diagnostic should be reported. Various fatal errors (e.g.,
/// template instantiation depth exceeded) fall into this category.
SFINAE_Report,
/// \brief The diagnostic is an access-control diagnostic, which will be
/// substitution failures in some contexts and reported in others.
SFINAE_AccessControl
};
Hay casos especiales en materia de control de acceso en el caso de SFINAE.
No lo creo.
11/4 "control miembros de acceso" (C++ 03):
La interpretación de un constructo dado se establece sin tener en cuenta al control de acceso. Si la interpretación establecida hace uso de nombres de los miembros o clases base inaccesible, está mal formada la construcción .
Así que la resolución de sobrecarga se produce primero, luego se aplica el control de acceso.
Hm, ¿pensé que se produciría sfinae si la construcción de la plantilla estaría bien informada? –
En realidad, parece que hay una disposición especial en ** [temp.deduct] ** para la sustitución. Ver §14.8.2/8 en mi respuesta. –
No. Estoy en el camino y no tengo un estándar para citarme, pero sfinae toma posiciones en la fase de compilación donde el compilador comprueba si el nombre existe, y en un control de acceso de fase posterior toma lugar.
Esto es similar a la resolución de sobrecarga, donde se consideran todos los nombres, y una coincidencia que es privada es mejor, pero no se compilará, aunque existe otra coincidencia que sería "aceptable" pero no privada.
Adición:
tema Core 1170 dice: comprobar
1170 Acceso plantilla durante la deducción argumento
Sección: 14.8.2 [temp.deduct]
Estado: FDIS Peticionario: Adamczyk Fecha: 2010-08-03[Votó en el WP en la reunión de marzo de 2011.]
De acuerdo con 14.8.2 [temp.deduct] párrafo 8,
comprobación acceso no se realiza como parte del proceso de sustitución. En consecuencia, cuando la deducción tiene éxito, aún se puede producir un error de acceso cuando se crea una instancia de la función.
Esto imita la forma en que se realiza la verificación de acceso en la resolución de sobrecarga. Sin embargo, la experiencia ha demostrado que esta exención de los errores de acceso de la falla de deducción complica significativamente la biblioteca estándar, por lo que esta regla debe modificarse.
propuesta de resolución (enero de 2011):
Cambio 14.8.2 [temp.deduct] párrafo 8 de la siguiente manera:
Si un cambio da como resultado un tipo o expresión no válida, el tipo de deducción falla . Un tipo o expresión no válida sería mal formado si se escribe utilizando los argumentos sustituidos. [Nota: la verificación de acceso no se realiza como parte del proceso de sustitución.-finalizar] En consecuencia, cuando la deducción tiene éxito, un error de acceso todavía podría cuando se crea una instancia de la función. Sólo los tipos válidos ...
Así que mi interpretación es que esto es imposible en C++ 03, pero C++ 11 lo hizo posible.
Aquí hay un ejemplo que implementa is_comparable y maneja un operador potencialmente privado ==. g ++ - 4.7 choques en esto, pero g ++ - 4.8 y clang ++ 3.4 lo manejan correctamente en el modo C++ 11.
#include <iostream>
#include <utility>
// is_comparable trait
template<class T>
class is_comparable {
template<typename U> static char (&check (int))[1 + sizeof (decltype (
std::declval<U>() == std::declval<U>() // trait check
))];
template<typename> static char (&check (...))[1];
public:
static constexpr const bool value = sizeof (check<T> (0)) != 1;
};
// tests
class Diff1 {}; // non-comparable
class Diff2 { // non-comprable, since member is private
bool operator== (const Diff2&);
};
struct EqM { bool operator== (EqM); }; // comparable
struct EqG {}; // comparable
bool operator== (const EqG&, const EqG&);
int
main()
{
std::cout << "is_comparable:";
std::cout << " void=" << is_comparable<void>::value;
std::cout << " Diff1=" << is_comparable<Diff1>::value;
std::cout << " Diff2=" << is_comparable<Diff2>::value;
std::cout << " int=" << is_comparable<int>::value;
std::cout << " EqM=" << is_comparable<EqM>::value;
std::cout << " EqG=" << is_comparable<EqG>::value;
std::cout << "\n";
return 0;
}
// $ clang++ is_comparable.cc -std=c++11 && ./a.out
// is_comparable: void=0 Diff1=0 Diff2=0 int=1 EqM=1 EqG=1
- 1. Cómo detectar violaciones de sincronización con Java
- 2. SFINAE + sizeof = detectar si la expresión compila
- 3. C++ ¿Algún consejo sobre cómo rastrear las violaciones de acceso?
- 4. Team Build: No se puede encontrar acceso privado generado
- 5. ¿Cómo detectar la existencia de una clase usando SFINAE?
- 6. SFINAE: detectar si la clase tiene la función libre
- 7. Acceso variable privado de PHP desde
- 8. SFINAE compilador preocupa
- 9. 'QObject :: QObject' no puede miembro privado de acceso declarado en la clase 'QObject'
- 10. Detect soporte del operador con decltype/SFINAE
- 11. ¿Qué es "Expresión SFINAE"?
- 12. Problema con SFINAE
- 13. SFINAE y detectar si un objeto de función C++ devuelve vacío
- 14. Github: acceso de solo lectura a un repositorio privado
- 15. ¿Cómo puedo dar acceso a un repositorio privado de GitHub?
- 16. Resharper: cómo desactivar el modificador de acceso 'privado'?
- 17. ¿Debería usar el modificador de acceso privado si es redundante?
- 18. C++ miembro función de acceso privado variable estática?
- 19. Java: acceso al constructor privado con parámetros de tipo
- 20. C++ ¿Es privado realmente privado?
- 21. sfinae busca miembro estático usando decltype
- 22. Android: cómo detectar un número privado mediante programación
- 23. Cuándo usar `static_assert` en lugar de SFINAE?
- 24. Detectar si un tipo se puede derivar de en C++
- 25. no puede miembro privado de acceso declarado en un error al crear la instancia de clase de plantilla
- 26. Diferenciación SFINAE entre firmado y no firmado
- 27. Por qué esto funciona (Plantillas, SFINAE). C++
- 28. ¿Cómo manejar las violaciones de restricción únicas de JPA?
- 29. SFINAE función miembro problema prueba de la existencia
- 30. Operador público nuevo, operador privado eliminar: obtener C2248 "no se puede acceder al miembro privado" cuando se usa el nuevo
... ¿realmente lo has probado? – Mehrdad
No, yo no lo probé. No sé de una implementación completamente conforme. –
@Mehrdad: pero ¿cómo interpretar el resultado de la prueba? Sabrá cómo lo interpreta * el compilador *, pero ¿cómo sabrá si el compilador cumple con las normas? –