Lo que digo a continuación (bajo POSTE ANTIGUO ) debería ser cierto hasta cierto punto, pero el problema real con esto es que SFINAE se usa incorrectamente, por lo tanto, ya no estoy tan seguro de que esto sea un error en gcc.
Una declaración de alias siempre debe tener éxito, no puede SFINAE allí, ya que no es una declaración de clase o función o especializaciones (eso tiene sentido, ya que no puede especializar alias). Si la declaración de alias no tiene éxito, el programa está mal formado. Por lo tanto, el compilador puede suponer que nunca llegará el caso de que la declaración de alias no tenga éxito hasta que lo obligue a crear una instancia de dicha plantilla.
Por lo tanto, es perfectamente aceptable que el compilador piense que sfinae_v_t<T,...>
siempre es así T
, ya que eso sucederá, cuando el programa no está mal formado. Por lo tanto, verá que en todos los casos en que el programa no está mal formado, la especialización parcial no se especializa y, como tal, le dirá que está mal formado. (Eso es lo que hace el ruido metálico).
No creo que el compilador se vea obligado a hacer esto. Y si no lo hace, y solo piensa "Ok, sfinae_v_t
es algún tipo, lo que sea", entonces no es obvio que esto sea una redeclaración. Así que creo que hasta que instanciamos uno de ellos no hay nada de malo en no arrojar un error.
Pero cuando lo instanciamos, debería existir el problema de que tenemos una redeclaración o que el programa está mal formado debido std::enable_if
, dependiendo del argumento de la plantilla. GCC debería recoger al menos uno de ellos, pero ninguno lo hace.
Esto tampoco se aplica absolutamente al ejemplo más fácil sin std::enable_if
. Así que todavía creo que esto es un error en GCC, pero estoy lo suficientemente loco como para no poder decir eso con certeza. Solo diría que alguien debería informarlo como un error y dejar que la gente de gcc lo piense.
ANTIGUA POST
Este es un error en gcc. El estándar nos da reglas para convertir una plantilla de clase en plantillas de función. Una plantilla de clase es más especializada que otra si su función es anterior a la otra en el orden de la plantilla de función parcial.
Creé las funciones aquí y ahora gcc afirma que llamarlas es ambiguo, por lo tanto, también tendría que decir que las plantillas de clase están igualmente especificadas.
Nota: Leyendo el estándar cuidadosamente, el compilador en mi cabeza está de acuerdo con el sonido metálico.