Operador de conversión: gcc vs clang
Considere el siguiente código (https://godbolt.org/z/s17aoczj6):
template<class T>
class Wrapper {
public:
explicit Wrapper(T t): _value(t) {}
template<class S = T>
operator T() { return _value; }
private:
T _value;
};
auto main() -> int {
auto i = int{0};
auto x = Wrapper<int>(i);
return x + i;
}
Compila con Clang, pero no con GCC (todas las versiones). Funciona en GCC al quitar la línea template<class S = T>
. ¿Este código es ilícito o uno de los compiladores está equivocado?
El error en GCC es error: no match for 'operator+' (operand types are 'Wrapper<int>' and 'int') return x + i;
.
Quiero una conversión a T
. El template no es necesario en este ejemplo, pero en un ejemplo no minimal quisiera usar SFINAE y, por lo tanto, necesitaría un template aquí.
davy.ai
Este código puede considerarse mal formado, ya que conduce a un error del compilador en una implementación (gcc) pero no en otra (clang). El error está relacionado con el uso del operador
+
con operandos de tipoWrapper<int>
eint
. La claseWrapper
proporciona un operador de conversión implícito al tipoT
, pero no a otros tipos comoint
, que es el segundo operando en la expresión.El uso de la plantilla en el operador de conversión no es estrictamente necesario en este ejemplo, pero puede ser útil en escenarios más complejos donde se necesita SFINAE. Sin embargo, debe tenerse en cuenta que el uso de plantillas puede conllevar problemas sutiles relacionados con la deducción de parámetros de plantilla y la resolución de sobrecarga, que pueden no ser consistentes en diferentes compiladores y versiones de lenguaje.
Por lo tanto, se recomienda probar y revisar cuidadosamente el código que depende de conversiones basadas en plantillas, especialmente cuando se trata de técnicas de programación basadas en restricciones como SFINAE.