2014-11-18 8 views
6

ben variadic şablonları genel bir sınıf yöntemini kabul ve çağırmak için kullandığı bir call fonksiyonu var aşağıdaki C++ 11 örnek var: kodunda yorumladığı gibitutarsız parametre paketi indirimi

#include <utility> 

template <typename T, typename R, typename... Args> 
R call(R (T::*fn)(Args...), T *t, Args&&... args) { 
    return ((*t).*fn)(std::forward<Args>(args)...);  
} 

class Calculator { 
    public: 
    int add(const int& a, const int& b) { 
     return a + b; 
    } 
}; 

int main() { 
    Calculator *calculator = new Calculator(); 
    int* a = new int(2);  
    int* b = new int(4); 

    // compiles 
    int res1 = calculator->add(*a, *b);  

    // does not compile! 
    int res2 = call<Calculator>(&Calculator::add,calculator, *a, *b);  

    return 0; 
} 

, int işlevini, const int kabul ettiğinde, yönlendirme yöntemini arayabiliyorum. Düzenli yürütme ile karşılaştırıldığında

error: no matching function for call to ‘call(int (Calculator::*)(const int&, const int&), Calculator*&, int&, int&)’ 
    int res2 = call<Calculator>(&Calculator::add,calculator, *a, *b);  
                    ^

inconsistent parameter pack deduction with ‘const int&’ and ‘int&’ 
    int res2 = call<Calculator>(&Calculator::add,calculator, *a, *b);  
                    ^

C++ variadic şablon sıkı tür denetlemesi zorlamak mı: Aşağıdaki derleme hatası alıyorum? Ben C++ 11.

+0

: * Not: Aday şablon göz ardı: parametresi için çakışan türleri çıkarılabilir 'Args' (<#define & #define &> vs. ) * – chris

+0

Bu, türlerin variadic şablonları kullanırken tam olarak eşleşmesi gerektiği anlamına mı geliyor? – jeffreyveon

+1

Bu, aynı şablon parametresi için farklı türler çıkaramazsınız çünkü derleyici, hangisini istediğinizi bilemez. Her zaman açık fonksiyon yakalama üzerinde atlayabilir ve sadece bir callable nesne parametresi olabilir: 'template otomatik arama (F f, T * t, Args && ... args) { dönüş (t -> * f) (std :: ileri (args) ...); } ' – chris

cevap

11

Eğer fonksiyon şablonu aradığınız yolu ile g ++ 4.8.1 kullanıyorum, şablon parametre paketi Args iki kaynaktan çıkarılabilir edilecektir:

  • üyesine pointer tipi fonksiyonu -, kesinti başarılı olabilmesi için int &, int &

gerekir exac çıkarılabilir sonucu - argümanlardan int (Calculator::*)(const int&, const int&)

  • fiili türleri (*a, *b) Eğer fonksiyon parametre paketi için geçti tly eşleşmesi. Belli ki yapmıyorlar.

    Bu, variadic şablonlarına yeni veya özel değil. std::max(1, 1.5) yapmayı denerseniz aynı soruna sahipsiniz - derleyici int bir argümandan diğerine double çıkarır ve iki çakışma nedeniyle kesinti başarısız olur.

    En basit muhtemelen iki paket alıyor düzeltme: Belki daha iyi clang en hatasını seveceksin

    template <typename T, typename R, typename... Args1, typename... Args2> 
    R call(R (T::*fn)(Args1...), T *t, Args2&&... args) { 
        return ((*t).*fn)(std::forward<Args2>(args)...);  
    } 
    
  • +0

    Elbette :) Teşekkürler. – jeffreyveon