2012-04-14 6 views

Antwort

2

können Sie schreiben, tatsächlich eine allgemeine Wrapper, dies zu erreichen:

template <typename T> 
class Lazy { 
public: 
    explicit Lazy(T const& t): _loader(), _item(t) {} 
    explicit Lazy(T&& t): _loader() _item(t) {} 
    explicit Lazy(std::function<T()> l): _loader(l), _item() {} 

    T& operator*() { return this->get(); } 
    T const& operator*() const { return this->get(); } 

    T* operator->() { return &this->get(); } 
    T const* operator->() const { return &this->get(); } 

private: 
    T& get() { if (not _item) { _item = _loader(); } return *_item; } 
    T const& get() const { if (not _item) { _item = _loader(); } return *_item; } 

    std::function<T()> _loader; 
    mutable boost::optional<T> _item; 
}; // class Lazy 

Diese Klasse garantiert, dass der Lader einmal ausgeführt wird, solange es vervollständigt. Wenn es nicht abgeschlossen wird, wird die Ausführung beim nächsten Zugriff wiederholt. Es ist nicht threadsicher.

Verbrauch:

// Output prime numbers as text 
bool isPrime(int); 
std::string toEnglish(int); 

void print(int i, Lazy<std::string> const& heavy) { 
    if (not isPrime(i)) { return; } 

    std::cout << *heavy << "\n"; 
} 

int main(int argc, char* argv[]) { 
    if (argc < 2) { return 1; } 

    int max = atoi(argv[1]); 
    for (int i = 2; i <= max; ++i) { 
     print(i, [=](){ return toEnglish(i); }); 
       // ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++11 lambda syntax 
    } 
} 

Hier wird toEnglish immer nur für Primzahlen aufgerufen.

+0

Danke, können Sie ein Beispiel für die Verwendung geben? Ich kann es kompilieren, habe aber keine Ahnung, wie man es benutzt. – fxam

+0

@fxam: sicher, hier gehen Sie :) –

+0

'Get()' ist privat, so dass Sie es nicht einfach in 'print' verwenden können. :) Ich habe das 'private:' um zwei Zeilen nach unten verschoben, da ich denke, dass du das eigentlich wolltest. Revert wenn nicht. Ich habe auch das Lambda geändert, da du eigentlich 'i' fangen musst. – Xeo