2015-08-14 20 views
12

ideone exampleİletme argümanlar


ben üye işleve bazı önceden tanımlanmış argümanları artı bazı kullanıcı geçirilen argümanlar ileri gerekir.

#define FWD(xs) ::std::forward<decltype(xs)>(xs) 

template<class T, class... Ts, class... TArgs> 
void forwarder(void(T::*fptr)(Ts...), TArgs&&... xs) 
{ 
    T instance; 
    (instance.*fptr)(FWD(xs)..., 0); 
    //       ^
    // example predefined argument 
} 

forwarder(&example::f0, 10, 'a'); 
forwarder(&example::f1, 10, "hello", 5); 

Bu, şablon olmayan üye işlevleri için uygun şekilde çalışır.

forwarder'a iletilen üye işlev işaretçisi, şablon işlevlerini de işaret edebilir.

prog.cpp:30:28: error: no matching function for call to 'forwarder(<unresolved overloaded function type>, int)' 
    forwarder(&example::f1, 10); 
          ^
prog.cpp:20:6: note: candidate: template<class T, class ... Ts, class ... TArgs> void forwarder(void (T::*)(Ts ...), TArgs&& ...) 
void forwarder(void(T::*fptr)(Ts...), TArgs&&... xs) 
    ^
prog.cpp:20:6: note: template argument deduction/substitution failed: 
prog.cpp:30:28: note: couldn't deduce template parameter 'T' 
    forwarder(&example::f1, 10); 

Ben derleyici yardım etmenin bir yolu doğru tipleri var anlamak mı:

struct example 
{ 
    void f0(int, int) { } 

    template<class T> 
    void f1(T&&, int) { } 
}; 

// Compiles 
forwarder(&example::f0, 10); 

// Does not compile 
forwarder(&example::f1, 10); 

hatalar: Ne yazık ki, derleyici bu durumda T tipini anlamak mümkün değildir forwarder arabirimini değiştirmeden?

Değilse, kullanıcı sözdizimini çok karışık hale getirmeden bu sorunu çözmenin en iyi yolu nedir?

DÜZENLEME: Ayrıca, üye fonksiyon işaretçisini bir şablon parametresi olarak, belki bir sarıcı yoluyla iletmek de kabul edilebilir. Hedef üye işlevi daima derleme zamanında bilinir. Sözdekod:

forwarder<WRAP<example::f0>>(10, 'a'); 
// Where WRAP can be a macro or a type alias. 

ideone example

+0

Hala belirsizlik sorununu çözmek için bir döküm gerçekleştirebilirsiniz ([örneğinizin bu çatalıyla] (http://ideone.com/942rPt)) ancak size uyacağından emin değilim ... – Caninonos

+0

Don ' Bu size uyacak mı bilmiyorum, ancak http://coliru.stacked-crooked.com/a/3507a8671c1162c2 – 0x499602D2

+0

@Caninonos: kullanıcı için yazmayı çok can sıkıcı görünüyor. Daha iyi bir çözüm yoksa, bir iletici 'iletici 'işlevi ve tüm aktarılan argümanlar için' decltype 'öğesine genişleyen basit bir makro yazabilirim ... ama bunu son çare olarak tutacağım. –

cevap

1

ben üye işlev işaretçisi şablon argümanları sunarak gcc 4.9 kodunuzu derlenmiş; bu

int main(){ 
// Compiles 
forwarder(&example::f0, 10); 
//Does not compile 
forwarder(&example::f1, 10); 
//Does compile, instantiate template with int or what ever you need 
forwarder(&example::f1<int>,10) 
} 

gibi ne olup bittiğini inanıyoruz şablon üye işlev örneğini gerekir olmasıdır. arayüzünüzü çok mu değiştiriyor? Herhangi bir cevabın, üye şablonunu bir şekilde örneklemek etrafında döneceğini düşünüyorum.