2015-01-26 21 views
10

Neden kimse onu çağırmamak yerine std :: ref çağırmayı tercih etmeli?std :: ref bu işlev için yararlı nedir?

template<class F, class...Ts> F for_each_arg(F f, Ts&&...a) { 
    return (void)initializer_list<int>{(ref(f)((Ts&&)a), 0)...}, f; 
    // why not return (void)initializer_list<int>{(f((Ts&&)a), 0)...}, f; 
} 
+2

Gereksiz. https://twitter.com/ericniebler/status/559798611991879684 – inf

cevap

17

std::reference_wrapper::operator() ne doğrudan işlev çağrısı olur ötesinde bazı durumlarda "sihirli" bir parça gerçekleştirir.

template <class... ArgTypes> 
result_of_t<T&(ArgTypes&&...)> 
operator()(ArgTypes&&... args) const; 

İade: Etkileri (N4296 [refwrap.invoke] alıntı) olarak belirtilir INVOKE(get(), std::forward<ArgTypes>(args)...). (20.9.2)

get() Ne reference_wrapper saran bir başvuru verir

. INVOKE 20.9.2 [func.require] anlatılan aşağıdaki gibidir:

INVOKE(f, t1, t2, ..., tN) tanımlayın:

(1.1) - (t1.*f)(t2, ..., tN)T ve t1 bir sınıfın bir elemanı işlevi için işaretçi f edildiğinde T türünün nesnesi veya T tipindeki bir nesneye yapılan bir başvuru veya T'dan türetilen bir nesneye yapılan bir başvuru;

(1,2) - ((*t1).*f)(t2, ..., tN)fT ve t1 önceki maddede tarif edilen türde bir olmayan bir sınıfın bir üyesi fonksiyonuna işaret eder;

(1,3) - t1.*fN == 1 ve fT ve t1 tip T bir amacı ya da tip T bir nesne ya da türetilmiş bir tipte bir nesne için bir başvuru için bir referans bir sınıf üyesi verilerine bir işaretçidir T;

(1,4) - (*t1).*fN == 1 ve fT ve t1 önceki maddede tarif edilen türde bir değil bir sınıf üyesi veri işaretçisi olduğunda; Diğer tüm durumlarda,

(1.5) - f(t1, t2, ..., tN).

ref(f) aramak yerine sadece f sonucu

olduğu işaretçi üyeli fonksiyon ve üye veri işaretçi-parametre olarak uygun bir nesne işaretçisi/referansla "olarak adlandırılan" olabilir. Örneğin,

struct A { void foo(); }; 
struct B : A {}; 
struct C : B {}; 
for_each_arg(&A::foo, A{}, B{}, C{}, std::make_unique<A>()); 

A, B ve C geçici nesneleri foo ve unique_ptr (DEMO) tutulan bir nesne çağırır. Neden ,'u'u f üzerinden kullanmayı tercih ederse, birinin for_each_arg numaralı telefonu kullandığı bağlama bağlı olduğu açıktır.

+0

İlginç, std :: reference_wrapper'ın bir başka sihirli özelliği. Eric Niebler'in neden gereksiz olduğunu düşündüğünü merak ediyorum. – inf

+0

@bamboon Daha fazla bağlam olmadan söylemek zor.Ref() 'nin 5 karakter daha eklediğini ve kod golf amaçları için daha kısa kodlarla sonuçlanacağını tahmin ediyorum. – Casey

+0

Neden "auto f = std :: ref (& A :: foo);" başarısız, ancak "auto f = & A :: foo; otomatik f2 = std :: ref (f) 'başarılı? – Barry

İlgili konular