error: type 'FirstClass' does not provide a call operator
Through this error the compiler is telling you that the type PrimeraClase
does not have a call operator ( does not provide a call operator ).
What is the call operator?
When a class overload the parentheses operator ( operator ()
) becomes a < a href="https://en.wikipedia.org/wiki/Funtor"> functor . That is, it becomes an object that can be called as if it were a function. We can see it in this example:
struct funtor
{
/* Operador de llamada que recibe un entero con signo, las
instancias de funtor podran ser llamadas como si fuesen una
funcion que recibe un numero */
void operator()(int numero) { std::cout << numero << '\n'; }
/* Operador de llamada que recibe una cadena de texto, las
instancias de funtor podran ser llamadas como si fuesen una
funcion que recibe un texto */
void operator()(std::string texto) { std::cout << texto << '\n'; }
};
struct clase_normal
{
};
funtor a, b;
clase_normal c, d;
a(42); // Llama a funtor::operator()(int), muestra '42'.
b("Abubilla!"); // Llama a funtor::operator()(std::string), muestra 'Abubilla!'.
a(b); // error: no existe funtor::operator()(funtor &);
b(c); // error: no existe funtor::operator()(clase_normal &);
c(42); // error: el tipo 'clase_normal' no provee un operador de llamada
d(42); // error: type 'clase_normal' does not provide a call operator
Why do you get this error?
You are confusing instances with types in function preguntar
:
void preguntar(PrimeraClase &Objeto1)
{
int num = 24;
string nom = "Sergio";
Objeto1(num,nom);
}
This function receives a instance of type PrimeraClase
; said instance is called Objeto1
. In the last line of function preguntar
you use the call operator with parameters int
and string
over the instance Objeto1
and given that the type PrimeraClase
does not provide a call operator that receives int
and string
, you receive the error.
Surely you thought you were calling the PrimeraClase
constructor passing the parameters corresponding to _valor
and _nombres
, but it is not, the instance you pass to preguntar
has been built (with the constructor without parameters ) in main
and then passed to the function preguntar
as instance.
What to do?
I assume you want the preguntar
function to ask the user for some data and then build an instance of PrimeraClase
with the data obtained; If so, you have the following options:
Return object built in the function .
PrimeraClase preguntar()
{
int num = 24;
string nom = "Sergio";
// Llamada a constructor, no a operador de llamada.
// Posiblemente se aplique RVO ( https://en.wikipedia.org/wiki/Return_value_optimization )
return PrimeraClase(num,nom);
}
int main()
{
cout << "Mi nombre es sergio\n";
// Obtiene el objeto construido dentro de la funcion preguntar
PrimeraClase Objeto1 = preguntar();
return 0;
}
This solution creates the object inside the function preguntar
and returns the object already built. In modern C ++ compilers the object is built only once, but if you are compiling with old compilers or with low optimization options it is possible to make two constructions of the object and one copy.
Values establishment and query functions .
If you want to work on already built objects to which you are going to modify the values they contain, you will need functions to establish and query values:
class PrimeraClase
{
int valor;
string nombres;
public:
PrimeraClase() :
valor(0),
nombres("Por favor ingrese un nombre\n")
{
cout << nombres << "y edad: " << valor << endl;
}
PrimeraClase(int _valor, string _nombres) :
valor(_valor),
nombres(_nombres)
{
cout << "su Nombre es: " << nombres << endl << "y su edad es: " << valor << endl;
}
void EstablecerValor(int _valor) { valor = _valor; }
void EstablecerNombres(int _nombres) { nombres = _nombres; }
};
Having these functions that establish the values of the class, the function preguntar
would look like this:
void preguntar(PrimeraClase &Objeto1)
{
int num = 24;
string nom = "Sergio";
Objeto1.EstablecerValor(num);
Objeto1.EstablecerNombres(nom);
}
int main()
{
PrimeraClase Objeto1;
cout << "Mi nombre es sergio\n";
preguntar(Objeto1);
return 0;
}
Other things to consider.