Risolto esercizio con funzione lambda

Mich87

Utente Iron
9 Maggio 2021
4
4
4
Ultima modifica:
Ciao a tutti,
sono nuovo del forum e sto cercando di migliorare le mie abilità da programmatore.
mi sono imbattuto in questo esercizio ed avrei bisogno di un po' di aiuto...

Non riesco a capire come funziona il costruttore di myClass a cui dovrei passare valori tramite la Lamda. Vorrei stampasse un certo numero di caramelle ma ne stampa sempre solo 0.

#include <iostream>
#include <vector>
#include <string>
#include <functional>
#include <memory>

class MyInterface
{
public:
MyInterface()
{
}
~MyInterface()
{
}

virtual void run() = 0;
};

class MyClass : public MyInterface
{
public:

size_t count;
std::vector<std::string> candies;

std::function<void(int)> function;

MyClass(const std::vector<std::string> strings, std::function<void(int)> function)
: candies(strings.size())
, function(function)
{
}
~MyClass()
{
stop();
}
void run() override
{
function(count);
for (size_t i = 0; i < count; i++)
std::cout << "I like candy.";
}
};
int main(int argc, wchar_t** argv) {
std::vector<std::string> strings;

int count = 0;

std::unique_ptr<MyInterface> myInstance(new MyClass(strings, [&](auto a)
{
count = a;
printf("%d amount of candy!", a);

}));

myInstance->run();

return count;
}

Vi ringrazio in anticipo per le eventuali risposte.
 

St3ve

Utente Platinum
12 Ottobre 2011
2,108
1,403
665
Vorrei stampasse un certo numero di caramelle ma ne stampa sempre solo 0.
Ne stampa sempre e solo zero perché non assegni nessun valore al counter delle caramelle, che è quindi inizializzato a zero perché: "Zero initialization is performed in the following situations (...) As part of value-initialization sequence for non-class types and for members of value-initialized class types that have no constructors, including value initialization of elements of aggregates for which no initializers are provided". Se all'interno della classe, linea 24, scrivi size_t count = 100; vedrai che il tuo codice ne stamperà sempre e solo 100.

Immagino che il problema reale sia altrove, perché fai anche cose che senza una dovuta motivazione sembrano abbastanza insensate. Il count = a; all'interno della lambda, ad esempio, non serve proprio a niente: stavi chiaramente cercando di fare altro, ma non so cosa. Se riesci a descriverci in modo abbastanza dettagliato cosa vuoi fare (...e non cosa hai fatto) magari riusciamo, o io o qualcun altro, a mostrarti qual'è il modo corretto di procedere.
 

Mich87

Utente Iron
9 Maggio 2021
4
4
4
Ultima modifica:
Ciao, ti ringrazio, in realtà nell'esercizio, piuttosto generico, si richiede di commentare il codice. Mi chiedevo però come mai, pur forzando 3 elementi all'interno di strings nel main, questi vengono inizializzati correttamente dal costruttore (stampando all'interno del costruttore la dimensione di candies risulta pari a 3), ma nel main vedo sempre 0 amount of candies e nel costruttore count è sempre zero.
 
DOWNLOAD
Supporta Inforge con una donazione

St3ve

Utente Platinum
12 Ottobre 2011
2,108
1,403
665
Ultima modifica:
Uhm... continuo a non capire perché ti aspetti un comportamento diverso. Facciamo che ti commento il codice all'interno della classe e vediamo se ti aiuta a schiarirti le idee.
C++:
class MyClass : public MyInterface {
public:
  size_t count;                       // 0 per la zero-initialization's rule
  std::vector<std::string> candies;   // inizializzato nel costruttore
  std::function<void(int)> function;  // inizializzato nel costruttore

  MyClass(const std::vector<std::string> strings, std::function<void(int)> function)
      : candies(strings.size()), function(function) {
      // Cosa possiamo dire di candies?
      // 1) è un vettore di stringhe
      // 2) è un vettore lunghezza strings.size()
      // ovvero, contiene strings.size() stringhe vuote
    
      // Cosa possiamo dire di function?
      // 1) è una funzione che prende un intero e non restituisce niente (void)
    
      // Cosa possiamo dire di count?
      // 1) è un intero che vale 0 e non lo stiamo modificando
  }

  ~MyClass() { /* stop(); */ }  // ???

  void run() override {
    function(count);

    // Cosa possiamo dire di function(count)?
    // 1) è equivalente a function(0), perché count vale 0
    // 2) è una funzione, non un metodo, quindi `count = a` non modifica this->count
    // 3) anche se non sapevi del punto 2: a vale 0 quindi sta facendo count = 0

    for (size_t i = 0; i < count; i++) std::cout << "I like candy.";

    // Cosa possiamo dire di questo for?
    // 1) visto che count (i.e., this->count) vale 0, il body non viene eseguito
  }
};

Forse volevi scrivere strings.size() al posto di count? Forse volevi scrivere count = strings.size() da qualche parte? Forse vuoi aggiungere un metodo add che incrementa il valore di count?

Prova a vedere se questo codice ti piace di più
C++:
#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include <vector>

class MyInterface {
public:
  virtual void run() = 0;
  virtual ~MyInterface() = default;
};

class MyClass : public MyInterface {
private:
  std::vector<std::string> candies;
  std::function<void(int)> function;

public:
  MyClass(const std::vector<std::string> &candies, std::function<void(int)> function)
      : candies(candies), function(function) {}

  void run() override {
    function(candies.size());
    for (const auto &c : candies) std::cout << "I like " << c << "\n";
  }
};

int main() {
  std::unique_ptr<MyInterface> myInstance(
      new MyClass(std::vector<std::string>{"Skittles", "Jawbreakers", "Twizzlers", "Smarties", "M&Ms"},
                  [](auto count) { std::cout << "There are " << count << " types of candies!\n"; })
  );

  myInstance->run();

  return 0;
}
 

Mich87

Utente Iron
9 Maggio 2021
4
4
4
Grazie mille, non ho scritto io il codice, era nel testo di un esercizio che chiedeva solo di commentarlo e modificarlo coerentemente alle osservazioni, senza una soluzione specifica. Probabilmente era ancora fuori dalla mia portata ma mi hai fatto capire molte cose. Grazie.