Здравствуйте.
Вот такая проблема:
#include <cstdlib>
#include <iostream>
using namespace std;
struct A {
template< class T, void(T::*TMethod)(void)>
static void f( T* obj ){
(obj->*TMethod)();
}
};
struct B {
void f() {
cout << "f()" << endl;
}
};
struct D : B {
};
int main() {
D d;
A::f<D,&D::f>(&d);
return 0;
}
Ошибка:
test.cpp: In function ‘int main()’:
test.cpp:24: error: no matching function for call to ‘A::f(D*)’
Не могу понять, что не так.
Здравствуйте, Аноним, Вы писали:
А мы так:
A::f<D, static_cast<void (D::*)(void)>(&D::f)>(&d);
Оказывается, выражение &D::f имеет тип void (B::*)(void), а компилятор по чём зря не будет кастить
шаблонный параметр void (B::*)(void) в void (D::*)(void) (не шаблонные, конечно, кастятся).
По-этому так можно:
struct A {
template< class T, class M>
static void f( T* obj, M TMethod ){
(obj->*TMethod)();
}
};
struct B {
void f() {
cout << "f()" << endl;
}
};
struct D : B {
};
int main() {
D d;
A::f<D>(&d, &D::f);
return 0;
}
Здравствуйте, -MyXa-, Вы писали:
MX>По-этому так можно:
Причём, TMethod может быть и не указателем на функцию-член, но и
— указателем на член-данное, для типа которого определён оператор ()
— произвольным типом, для которого перегружен оператор ->*, для результата которого определён оператор ()
http://codepad.org/svJSx0Jl
#define CPFE cout << __PRETTY_FUNCTION__ << endl;
template<class X, class Y>
void foo(X x, Y y)
{
CPFE;
(x->*y)();
cout << endl;
}
struct H
{
void operator() () const { CPFE; }
};
struct I {};
struct J {};
struct A
{
void f() { CPFE; } // функция-член
void (*g)(); // указатель на свободную функцию
H h; // указатель на функциональный объект
};
H operator ->* (A* a, I i) { CPFE; return H(); } // I в роли указателя на член
H operator ->* (A& a, J j) { CPFE; return H(); } // внезапно, A в роли указателя на непойми что!
void ag() { CPFE; }
int main()
{
A a; a.g = ag;
foo(&a, &A::f);
foo(&a, &A::g);
foo(&a, &A::h);
foo(&a, I());
foo( a, J());
}
Но это немножко не то. У топикстартера — на выходе унарная функция, принимающая только объект. То есть, это биндер времени компиляции.
А биндер времени исполнения — это любой дурак может. Хоть руками, хоть на бусте...
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте.
А>Вот такая проблема:
А>
А>#include <cstdlib>
А>#include <iostream>
А>using namespace std;
А>struct A {
А> template< class T, void(T::*TMethod)(void)>
А> static void f( T* obj ){
А> (obj->*TMethod)();
А> }
А>};
А>struct B {
А> void f() {
А> cout << "f()" << endl;
А> }
А>};
А>struct D : B {
А>};
А>int main() {
А> D d;
А> A::f<D,&D::f>(&d);
А> return 0;
А>}
А>
А>Ошибка:
А>test.cpp: In function ‘int main()’:
А>test.cpp:24: error: no matching function for call to ‘A::f(D*)’
А>Не могу понять, что не так.
#include <cstdlib>
#include <iostream>
using namespace std;
struct A
{
template< typename T, void(T::* TMethod)(void)>
static void f( T* obj )
{
( obj->*TMethod )();
}
};
struct B
{
void f()
{
cout << "f()" << endl;
}
};
struct D : B
{
void f1()
{
cout << "f1()" << endl;
}
};
int main()
{
D d;
A::f< B, &B::f >( &d ); (1)
A::f< B, &D::f >( &d ); (2)
A::f< D, &D::f >( &d ); (3)
A::f< D, &D::f1 >( &d );(4)
return 0;
}
в точке инстанцирования (3)
C++: g++ 4.1.2 : error: no matching function for call to 'A::f(D*)'
VC2008 — более разговорчив
error C2440: 'specialization' : cannot convert from 'void (__thiscall B::* )(void)' to 'void (__thiscall D::* const )(void)'
Standard conversion from pointer-to-member of base to pointer-to-member of derived is not applied for template arguments
error C2973: 'A::f' : invalid template argument 'void (__thiscall B::* )(void)' see declaration of 'A::f'