2010-12-06 25 views
25

nasıl bir yöntemin belirli bir aşırı bir yöntem işaretçisi alırım:C++ aşırı yüklü yöntem işaretçi

struct A { 
    void f(); 
    void f(int); 
    void g(); 
}; 

Ben

&A::g 

g bir işaretçi olduğunu biliyoruz. Ancak f veya f(int) işaretçisini nasıl edinebilirim?

cevap

32
(void (A::*)()) &A::f 
(void (A::*)(int)) &A::f 

fonksiyon işaretçileri ve üye işlev işaretçileri bu özellik vardır - aşırı yük sonucu atanmış veya dökme ne kadar çözülebilir.

fonksiyonlar statik ise, o zaman sıradan fonksiyonları olarak kabul etmeniz gerekir:

(void (*)()) &A::f; 
(void (*)(int)) &A::f; 

hatta

(void (*)()) A::f; 
(void (*)(int)) A::f; 
+0

Teşekkürler! Üye işlevleri statik ise ne olur? (Hata alıyorum: bağlamsal tip bilgisi olmayan aşırı yüklenmiş fonksiyonun adresi) –

+0

@Neil: Benim düzenlemeye bakın –

+0

Oh, görüyorum, sadece ilk A :: 'statik fonksiyonlar için düzenli işaretçilere yayınlanacak. Beni buna dövüyorsun :) –

9

Sadece belirsizlik çıkarmak için &A::f sonucunu döküm zorunda :

static_cast<void (A::*)()>(&A::f); // pointer to parameterless f 
static_cast<void (A::*)(int)>(&A::f); // pointer to f which takes an int 
+0

Imho, SE'ye C++ hakkında gönderilen en büyük mesajlardan biri ... – peterh

5

Aşağıdaki fikir için Stefan Pabst'a teşekkürler. ACC, ACCU 2015'te beş dakikalık bir yıldırım konuşması yaptı. Ekstra çifti yazmaktan kaçınmak için, cv niteleyici ve/veya referans niteleyicisi ve C++ 17 değişken şablonu ile aşırı yüklenmelerin çözümlenmesine izin vermek için etiket türleri ile genişlettim. Aksi halde gerekli olan parantezler.

Bu çözüm, döküm tabanlı yanıtlarla aynı prensipte çalışır, ancak işlevin dönüş türünü veya üye işlevlerinde, işlevin bir sınıf olduğu sınıfın adını değiştirmek zorunda kalmazsınız. derleyici olarak bu şeyleri çıkartabiliyor.

bool free_func(int, int) { return 42; } 
char free_func(int, float) { return true; } 
struct foo { 
    void mem_func(int) {} 
    void mem_func(int) const {} 
    void mem_func(long double) const {} 
}; 

int main() { 
    auto f1 = underload<int, float>(free_func); 
    auto f2 = underload<long double>(&foo::mem_func); 
    auto f3 = underload<cv_none, int>(&foo::mem_func); 
    auto f4 = underload<cv_const, int>(&foo::mem_func); 
} 

underload şablonu uygulayan kod here olduğunu.

İlgili konular