error: type 'FirstClass' does not provide a call operator

1

I'm trying to pass an object as parameter but I get an error that I did not provide a call to the object.

I want to use the second definition of the constructor, so I pass it as a parameter to be able to enter the variables by default.

This is my code:

#include <iostream>
using namespace std;

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 preguntar(PrimeraClase &Objeto1)
{
    int num = 24;
    string nom = "Sergio";

    Objeto1(num,nom);
}

int main()
{
    PrimeraClase Objeto1;
    cout << "Mi nombre es sergio\n";
    preguntar(Objeto1);

    return 0;
}

And this is the error that I get when I compile.

eje05.cpp:22:2: error: type 'PrimeraClase' does not provide a
      call operator
        Objeto1(num,nom);

Thank you very much for your help.

    
asked by Mucacran 13.03.2017 в 21:48
source

3 answers

2

The problem occurs in your code, it is in this function:

void preguntar(PrimeraClase &Objeto1)
{
        int num = 24;
        string nom = "Sergio";

        Objeto1(num,nom); <-- Sobretodo en esta linea
}

In this line what you are trying to do is call the Objeto1 , as if it were a function Objeto1(num, nom) , that is why it throws you that error.

  

error: type 'FirstClass' does not provide a call operator

What does this mean?

When calling Objeto1(num, nom) you are calling it as if it were a function, that is, using the operator () , but since no call operator is found (as you already know) explained by @eferion) this operation can not be performed.

Solution

There are several solutions, as you can see, you can initialize the object of type PrimeraClase and return it. (Based on the response of PaperBirdMaster) , this will allow us that the instantiation of the object and the passing of the parameters to the constructor are done in the same line and thus we will return to the already initialized object.

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);
}

Another possible solution to your problem, would be the one that I propose below:

By having the parameter Objeto1 which is of type PrimeraClase what we can do is re-initialize it , which means that, we can do the times of a statement and how you use the operator & which passes us by reference to said object, you can re-initialize it, passing the parameters of the constructor there.

void preguntar(PrimeraClase &Objeto1)
{
        int num = 24;
        string nom = "Sergio";

        Objeto1 = PrimeraClase(num,nom); <--- Llamamos nuevamente al constructor de PrimeraClase
}

What would leave your code like this:

#include <iostream>
using namespace std;

class PrimeraClase
{

private:
   int valor;
   string nombres;

public:
   PrimeraClase();
   PrimeraClase(int _valor, string _nombres);

};

PrimeraClase::PrimeraClase() : valor(0),nombres("Por favor ingrese un nombre\n")
{
        cout << nombres << "y " "edad: " << valor << endl;
}

PrimeraClase::PrimeraClase(int _valor, string _nombres) : valor(_valor),nombres(_nombres)
{
        cout << "su Nombre es: " << nombres << endl <<
                "y su edad es: " << valor << endl;
}

void preguntar(PrimeraClase &Objeto1)
{
        int num = 24;
        string nom = "Sergio";

        Objeto1 = PrimeraClase(num, nom);
}


int main()
{
        PrimeraClase Objeto1;
        cout << "Mi nombre es sergio\n";
        preguntar(Objeto1);

        return 0;
}

Result:

Por favor ingrese un nombre
y edad: 0
Mi nombre es sergio
su Nombre es: Sergio
y su edad es: 24
    
answered by 13.03.2017 / 21:58
source
2
  

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.

answered by 14.03.2017 в 09:18
1
  

I'm trying to pass an object as parameter but I get an error that I did not provide a call to the object.

Let's look at the code:

void preguntar(PrimeraClase &Objeto1)
{
    int num = 24;
    string nom = "Sergio";

    Objeto1(num,nom); // <<--- AQUI
}

The instruction that I highlight for you with the comment is trying to call the operator function of object Objeto1 . This object does not have a valid function operator and hence the error.

I do not think that at the moment you need to know what the function operator is, so I'll skip that part. The fact is that the compiler is not able to find a valid function operator and that is why it aborts the process and shows you an error.

  

I want to use the second definition of the constructor, so I pass it as a parameter to be able to enter the variables by default.

If you want to modify the object from the second constructor, you must bear in mind that the constructors are only called when creating new objects, then the mechanics to follow would be to create a new object and then make an assignment:

void preguntar(PrimeraClase &Objeto1)
{
    int num = 24;
    string nom = "Sergio";

    Objeto1 = PrimeraClase(num,nom);
}

There would be other possibilities, such as enabling functions to modify member values without resorting to these devices:

class PrimeraClase
{
    int valor;
    string nombres;
public:

    PrimeraClase();
    PrimeraClase(int _valor, string _nombres);

    // Funciones individuales
    void SetValor(int valor)
    { this->valor = valor; }

    void SetNombres(const std::string& nombres)
    { this->nombres = nombres; }

    // Todo en uno
    void SetValores(int valor, const std::string& nombres)
    {
      this->valor = valor;
      this->nombres = nombres;
    }
};

void preguntar(PrimeraClase &Objeto1)
{
    int num = 24;
    string nom = "Sergio";

    // opcion 1
    Objeto1.SetValor(num);
    Objeto1.SetNombres(nom);

    // opcion 2
    Objeto1.SetValores(num,nom);
}
    
answered by 14.03.2017 в 09:31