2012-08-17 28 views
15

2 değeri ve bir functor veya bir lambda kabul eden bir şablon işlevi yazmak istiyorum. Fonksiyon, functor'ı bu değerlerle çağırır ve sonucu döndürür.Functor'ın dönüş değeri nasıl hesaplanır?

template <typename T, typename Fn> 
_ReturnTypeOfPred_ Apply(T x, T y, Fn fn) 
    { 
    return fn(x, y); 
    } 

Soru: Apply dönüş türünü tanımlamak nasıl Fn dönüş türü eşit olmak? Bu 1 örnek basitleştirilmiş edildi

funktor

template <typename T> 
auto Sum(T x, T y) -> decltype(x+y) 
    { 
    return x+y; 
    } 

Güncelleme bu örnekte olduğu gibi T için mutlaka eşit değildir. Bu bir işe yarıyor mu? Ben dönüş türü decltype yılında return ifadesini tekrarlamak durumunda

template <typename TContainer, typename Fn> auto Apply(const TContainer& x, const TContainer& y, Fn fn) -> decltype(fn(x.front(), y.front())) { return fn(x.front(), y.front()); } 

hep işe yarar mı? Daha zarif bir yolu var mı?

+2

Alt-başkent isimleri uygulama için ayrılmıştır. Bunları kendi kodunuzda kullanmamalısınız. –

+2

@KerrekSB: Gerçek bir kod değil, gerçek bir kod – Andrey

+0

İyi funktörler (STL'de olduğu gibi) her zaman kendi 'return_type'lerini tanımlar, böylece sadece' Fn :: return_type' kullanabilirsiniz. Ama anladığım kadarıyla, iyi-fun-funtörler için de çalışan bir cevap istiyorsun. – Gorpik

cevap

18

Neredeyse bitti; Sadece decltype kullanın:

template <typename T, typename Fn> 
auto Apply(T x, T y, Fn fn) -> decltype(fn(x, y)) 
{ 
    return fn(x, y); 
} 

Sen std::result_of (Difference between std::result_of and decltype) ama neden rahatsız kullanabilir? Takip soruya gelince

template <typename T, typename Fn> 
typename std::result_of<Fn, T, T>::type Apply(T x, T y, Fn fn) 
{ 
    return fn(x, y); 
} 

: hata eğilimli olabilir ama, decltype(<expression>) olacak genellikle çalışma ile return-type yerine bir fonksiyonu

auto fn(<args>) -> <return-type> { return <expression>; } 

için. Örneğin, göz önünde bulundurun:

İşte decltype
auto f(char c) -> decltype(std::string() += c) { return std::string() += c; } 

std::string & verecektir ve işlevi, bir yerel bir lvalue başvuru dönecektir! örneğin olma nedeni iade olmayan bir değer elde olabilir Diğer durumlarda

auto f(char c) -> std::remove_reference<decltype(std::string() += c)>::type { 
    return std::string() += c; 
} 

, <expression>: Bu şekilde değiştirilmesi gerekir Bir lambda, vb. içeren kopçasız, vb.

+0

Teşekkür ederiz, güncellenmiş soruya bir göz atabilir misiniz? – Andrey

+0

@Andrey yukarıya bakın. – ecatmur

+0

Bağladığınız soru, std :: result_of' ve 'decltype' arasındaki farkların gerçekten iyi olmadığını vurgulamıyor. OP'nin amaçları için, 'std :: result_of' uygun değildir. –