2016-05-02 33 views
6

Çeşitli girdiler için aşırı yüklenen process yöntemine sahip bir sınıfım var Filter.Tüm aşırı yüklenmiş yöntemler için takma ad?

template< typename T > 
class Filter 
{ 
public: 
    void process(T arr[], size_t len); 
    T process(T one_value); 
    void process(std::array &arr); 
    void process(std::vector &v); 
    //... many other variants 

    using operator() = process; // How to write proper? 
} 

Ben process ihmal kullanıcı kodu basitleştirmek istiyorum: filter.process(values)filter(values) haline gelecektir. Her varyant için aşırı yüklenmiş bir operator() yazmanın iyi bir fikir olduğunu sanmıyorum. Daha uygun bir çözüm var mı?

cevap

7

Zaten karışımda şablonlarınız olduğundan; neden varadik bir şablonu denemiyoruz?

Alternatif olarak; referanslar geri gönderilirse, aşırı yüklenmelerin bir kısmını oluşturur (OP'de gösterilmez);

daha eksiksiz ve daha geniş kullanım durumları için
template <typename... Args> 
decltype(auto) operator()(Args&&... args) 
// caters for reference returns 
{ 
    return process(std::forward<Args>(args)...); 
} 

; eğer istenirse, aşağıdakiler SFINAE dostu davranışı ve derleyiciye bağlı olarak daha kısa/daha kolay hata mesajları sunar;

template <typename... Args> 
auto operator()(Args&&... args) -> decltype(process(std::forward<Args>(args)...)) 
// SFINAE support using a trailing decltype 
{ 
    return process(std::forward<Args>(args)...); 
} 
+0

:

Hemen şöyle yerine kurucular içine tüm bu aşırı yüklenmeleri olun. –

+2

Herhangi bir tür denetimi atlamak yok, ya da hiçbir dönüşüm yoktur. 'process' argümanı' operator() ''e verildiği gibi alacaktır. – Niall

+4

@DanKorn Bence, mevcut standartlara uyan C++ kodu ile C++ 'etiketine cevap vermek oldukça yaygın. Yani, ben 'C++ 'etiketi C++ 03 veya başka herhangi bir özel standart anlamına gelmez sanmıyorum. –

8

Tabii, sadece, operator() şablon Evrensel Referans kullanın ve process argümanlar mükemmel-iletin. Sebep, uygun başlığı eklemeniz gerekir. Ancak

template< typename T > 
class Filter 
{ 
public: 
    void process(T arr[], size_t len); 
    T process(T one_value); 
    void process(std::array &arr); 
    void process(std::vector &v); 
    //... many other variants 

    template<typename... Y> 
    auto operator() (Y&&... y) 
     -> decltype(process(std::declval<Y>()...)) 
    { 
     return process(std::forward<Y>(y)...); 
    } 
} 

, operator()(...) önce process her aşırı yük ilan edilmesi gerektiğine dikkat -, soruyu düzenlenmiş sayesinde TC

+0

Sanırım, diğer insanlar için cevabımı C++ 14'ün geliştirilmiş “otomatik” dönüş tipi kesintisinin sadeliğini Nail'ın cevabında gösterildiği gibi göreceğim. – WhiZTiM

+1

@ T.C. Declval’e ihtiyacımız var mı? Belki sadece decltype (süreç (std :: ileri (y) ...)) '? – Barry

-4

Tamam, yani bu şimdi sorduğun buysa cevapları, spesifik olarak "I want kullanıcı kodu ihmal sürecini basitleştirin: filter.process (values), filtre (değerler) olur. " derleyici tarafindan tamamen baypas tür denetim istiyor ve potansiyel olarak daha sonra emin, devam edin ince hata bir çok tanıtmak Eğer

template< typename T > 
class Filter 
{ 
public: 
    void Filter(T arr[], size_t len); 
    T Filter(T one_value); 
    void Filter(std::array &arr); 
    void Filter(std::vector &v); 
    //... many other variants 
}; 
+1

Bu, OP'nin filtreyi nasıl çağırmak istediğiyle eşleşmiyor. – NathanOliver

İlgili konular