Domanda Risolto esercizio con funzione lambda

Mich87

Utente Iron
9 Maggio 2021
4
2
4
8
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.
 
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.
 
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.
 
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;
}
 
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.