2016-03-10 10 views
5

Bundan daha Finalizer sınıfı yazmanın daha genel bir yolu var mı? MümkünEl ile sınıf şablon parametresi belirtiminden nasıl kurtulur

Finalizer finalizer([]() { std::cout << "str" << std::endl; }); 

mi:

istediğim
#include <functional> 
#include <iostream> 

template <typename T> 
class Finalizer 
{ 
public: 
    Finalizer(const std::function<T>& f) : _f(f) {} 

    ~Finalizer() 
    { 
     _f(); 
    } 

private: 
    std::function<T> _f; 
}; 

int main() 
{ 
    Finalizer<void()> finalizer([]() { std::cout << "str" << std::endl; }); 
} 

böyle kod yazmak edebilmek için manuel sınıf şablonu parametre şartname kurtulmak için?

+0

? Veya varsayılan bir şablon parametresi 'typename T = void() 'verilsin mi? – Garf365

+0

@ Garf365 Daha genel olması için. Bazı finalizer yöntemleri aslında hata kodlarını döndüren ayrı bir işlev olabilir ama ben bunları zaten 'Finalizer' sınıfında kullanmak istiyorum ve hata kodlarını yok sayıyorum. – FrozenHeart

+0

@FrozenHeart 'std :: function ' otomatik olarak yoksayılacak Sonuç, burada sorun yok. – lisyarus

cevap

5

C++ türünde kesinti, sınıf şablonları için değil, yalnızca işlev şablonları için kullanılabilir. Şablon bağımsız değişkeni yapmak için make_finalizer işlevine gereksiniminiz vardır.

Ayrıca, gerçekten silinmesini istemediğiniz sürece, çalışma zamanı maliyetini ödemeye gerek kalmadan std::function'u kullanmanız gerekmez.

template <typename F> 
class Finalizer 
{ 
public: 
    Finalizer(const F & c) : f_(c) {} 
    Finalizer(F && c) : f_(std::move(c)) {} 
    Finalizer(const Finalizer &) = delete; 
    Finalizer(Finalizer && other) : 
      valid_(other.valid), 
      f_(std::move(other.f_)) 
    { 
     other.valid_ = false; 
    } 

    Finalizer& operator=(const Finalizer &) = delete; 
    Finalizer& operator=(Finalizer && other) 
    { 
     Finalizer tmp(std::move(other)); 
     swap(tmp); 
     return *this; 
    } 

    ~Finalizer() 
    { 
     if (valid_) 
      f_(); 
    } 

    void swap(Finalizer & other) noexcept 
    { 
     using std::swap; 
     swap(other.valid_, valid_); 
     swap(other.f_, f_); 
    } 

private: 
    bool valid_ = true; 
    F f_; 
}; 

template<class F> 
Finalizer< std::remove_reference_t<F> > at_scope_exit(F && x) 
{ 
    return Finalizer< std::remove_reference_t<F> >(std::forward<F>(x)); 
} 

Ve oto ile kullanmak: Neden `doğrudan std :: fonksiyonunu ` yazmıyor

auto x = at_scope_exit([]() { std::cout << "Hello world" << std::endl; }); 
+0

Neden std :: forward' aramasına ihtiyacım var? – FrozenHeart

+0

@FrozenHeart, lambda'yı taşımak yerine "Sonlandırıcı" içine kopyalamak isteyebilirsiniz. – sbabbi

İlgili konular