2013-04-05 23 views
17

Mat adlı sınıfımda, başka bir işlevi parametre olarak alan bir işleve sahip olmak istiyorum. Şu anda aşağıdaki 4 işlevi var, ancak print() öğesini çağırırken bir hata alıyorum. İkinci satır bana bir hata veriyor, ama nedenini anlayamıyorum, çünkü ilk çalışma. Tek fark, f işlevinin Mat sınıfının bir üyesi değil, f2 ise işlevidir. başarısızlık: error: no matching function for call to Mat::test(< unresolved overloaded function type>, int)'C++ - <çözümlenmemiş aşırı yüklenmiş işlev türü>

template <typename F> 
int Mat::test(F f, int v){ 
    return f(v); 
} 

int Mat::f2(int x){ 
    return x*x; 
} 

int f(int x){ 
    return x*x; 
} 

void Mat::print(){ 
    printf("%d\n",test(f ,5)); // works 
    printf("%d\n",test(f2 ,5)); // does not work 
} 

Bunun nedeni nedir?

+1

'f2' statik mi değil mi? –

+0

Printf aramayı printf olarak değiştirmeyi deneyin ("% d \ n", test (Mat :: f2, 5)); – 2to1mux

+0

'f2''de birden fazla aşırı yüklenme var mı? –

cevap

3

Burada sorun, Mat üzerinde f2 bir yöntemdir, f ise sadece bir işlevdir. Kendi başına f2'u arayamazsınız, bunu çağırmak için Mat örneğine ihtiyaç duyar. Bu çevrede en kolay yolu olabilir:

printf("%d\n", test([=](int v){return this->f2(v);}, 5)); 

= sen f2 aramak için gerekenleri olan this orada yakalayacaktır.

+0

f2 ve baskı her ikisi de Mat'ın üye işlevleri olduğundan, Mat nesnesine başvurmaksızın f2 çağırmasına izin verilmiyor mu? – 2to1mux

+0

Vay, bu (orijinal koddan birkaç tweaks ile) çalışır. +1 benden –

+0

-1. hata mesajı, aşırı yüklenen bir işlev nedeniyle hatanın meydana geldiğini ve işlev şablonunun işlev çağrısı sözdiziminin yanlış olduğunu (bunun ne demek olduğunu) söylemediğini söyler. –

31

pointer-to-member-function'un türü pointer-to-function'dan farklıdır.

bir fonksiyonun tip sıradan bir fonksiyon ya da bazı sınıfın bir statik olmayan üye işlevi olmasına bağlı olarak farklıdır:

int f(int x); 
the type is "int (*)(int)" // since it is an ordinary function 

Ve

int Mat::f2(int x); 
the type is "int (Mat::*)(int)" // since it is a non-static member function of class Mat 

Not: eğer Bu, Fred'in statik bir üyesi işlevidir, türü, sıradan bir işlevmiş gibi aynıdır: "int (*)(char,float)"

In C++, member functions have an implicit parameter which points to the object (the this pointer inside the member function). Normal C functions can be thought of as having a different calling convention from member functions, so the types of their pointers (pointer-to-member-function vs pointer-to-function) are different and incompatible. C++ introduces a new type of pointer, called a pointer-to-member, which can be invoked only by providing an object.

NOTE: do not attempt to "cast" a pointer-to-member-function into a pointer-to-function; the result is undefined and probably disastrous. E.g., a pointer-to-member-function is not required to contain the machine address of the appropriate function. As was said in the last example, if you have a pointer to a regular C function, use either a top-level (non-member) function, or a static (class) member function.

Daha fazlası bu Here ve here.

+0

Ancak bu neden şablonun nedenini açıklamıyor onu çözemezsin. Yoksa bir şey mi özlüyorum? –

+0

@LuchianGrigore Bu şekilde anladım. Derleyici, bir "çağrı işleci" sağlayan bir tür bekler veya Mat :: Test'ten erişilebilen int (int) ile eşleşen bir işlev bulabilir. Ve yukarıdaki açıklamaya göre 'işaretçi-üye işlevine karşı işaretçi-işlev-işlevi farklı ve uyumsuz'. Yani, bu '> f2' işleviyle eşleşmez. Bu sadece benim anlayışım. Bunu daha önce hiç bilmiyordum :) –

+0

Linkler ölü gibi görünüyor. – derM

İlgili konular