Tengo una plantilla de función que toma muchos tipos diferentes como entrada. De esos tipos, solo uno de ellos tiene una getInt()
función. Por lo tanto, quiero que el código ejecute la función solo para ese tipo. Por favor sugiera una solución. Gracias
#include <type_traits>
#include <typeinfo>
class X {
public:
int getInt(){
return 9;
}
};
class Y{
};
template<typename T>
void f(T& v){
// error: 'class Y' has no member named 'getInt'
// also tried std::is_same<T, X>::value
if(typeid(T).name() == typeid(X).name()){
int i = v.getInt();// I want this to be called for X only
}
}
int main(){
Y y;
f(y);
}
type_info
estructura tiene un operador de comparación de igualdad , por lotypeid(T) == typeid(X)
que también debería funcionar.if constexpr
con condiciónis_same_v<T,X>
.getInt
miembro invocable . Debe haber bastantes preguntas aquí en stackoverflow.com solo sobre cómo ver si una estructura o clase tiene una función miembro específica, si solo busca un poco.Respuestas:
Si desea poder llamar a una función
f
para todos los tipos que tienen miembro de funcióngetInt
, no soloX
, puede declarar 2 sobrecargas para la funciónf
:para los tipos que tienen
getInt
función miembro, incluida la claseX
para todos los demás tipos, incluida la clase
Y
.Solución C ++ 11 / C ++ 17
Teniendo eso en mente, podrías hacer algo como esto:
Compruébalo en vivo .
Tenga en cuenta que
std::void_t
se introdujo en C ++ 17, pero si está limitado a C ++ 11, entonces es realmente fácil de implementarvoid_t
por su cuenta:Y aquí está la versión C ++ 11 en vivo .
¿Qué tenemos en C ++ 20?
C ++ 20 trae muchas cosas buenas y una de ellas son los conceptos . Lo anterior que es válido para C ++ 11 / C ++ 14 / C ++ 17 se puede reducir significativamente en C ++ 20:
Compruébalo en vivo .
fuente
void_t
embargo, antes de C ++ 17, esa implementación causa problemas a algún compilador antiguo (como lo señala el enlace).template<typename T> concept HasGetInt = requires (T& v) { {v.getInt()} -> std::convertible_to<int>; };
Puede usar
if constexpr
desde C ++ 17:Antes, tendrá que usar sobrecargas y SFINAE o envío de etiquetas.
fuente
if constexpr
es una característica de C ++ 17.X
Mantenlo simple y sobrecargado. Ha trabajado desde al menos C ++ 98 ...
Esto es suficiente si solo hay un tipo con
getInt
función. Si hay más, ya no es tan simple. Hay varias formas de hacerlo, aquí hay una:Ejemplo en vivo con salida de diagnóstico.
fuente
X
), pero, si hubiera más tipos similares con miembrogetInt
en el futuro, esta no es una buena práctica. Probablemente quieras notar eso