2012-04-14 2 views
4

나는 Demeter의 법칙에 복종하고 싶습니다. 그러나 나는 또한 생성자에게 전달 된 객체들을 게으른로드하고 싶다. 어떻게 구현해야합니까? 래퍼 클래스를 전달 하시겠습니까? 함수 포인터를 전달 하시겠습니까? 로더만큼이 완료로, 한 번 실행되는 것을Demeter의 법칙을 준수하면서 게으른로드하는 법?

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 

이 클래스 보증 :

답변

2

는 실제로이를 일반적인 래퍼를 작성할 수 있습니다. 완료되지 않으면 실행은 다음 액세스에서 재 시도됩니다. 스레드로부터 안전하지는 않습니다.

사용법 : 여기

// 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 
    } 
} 

, toEnglish는 오직 소수를 위해 호출됩니다.

+0

감사합니다. 사용 방법에 대한 예제를 제공해 주실 수 있습니까? 나는 그것을 컴파일 할 수 있지만 사용법에 대한 단서가 없다. – fxam

+0

@fxam : 확실히 여기 있습니다. –

+0

'get()'은 private이므로'print'에서 사용할 수 없습니다. :) 나는 그것이 당신이 실제로 의도 한 것이라고 생각하기 때문에'private :'두 줄을 아래로 옮겼습니다. 그렇지 않으면 되돌립니다. 나는'i'를 실제로 잡아야하기 때문에 람다를 변경했습니다. – Xeo

관련 문제