Функция член базового класса в кач-ве параметра. Ошибка
От: Аноним  
Дата: 19.12.09 02:46
Оценка:
Здравствуйте.

Вот такая проблема:


#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*)’

Не могу понять, что не так.
Re: Функция член базового класса в кач-ве параметра. Ошибка
От: -MyXa- Россия  
Дата: 19.12.09 05:28
Оценка:
Здравствуйте, Аноним, Вы писали:

А мы так:
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;
}
Если не поможет, будем действовать током... 600 Вольт (C)
Re[2]: Функция член базового класса в кач-ве параметра. Ошиб
От: Кодт Россия  
Дата: 21.12.09 12:33
Оценка:
Здравствуйте, -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>>
Перекуём баги на фичи!
Re: Функция член базового класса в кач-ве параметра. Ошибка
От: Владислав Курмаз Украина http://tis-method.org/
Дата: 22.12.09 08:52
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте.


А>Вот такая проблема:


А>

А>#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'
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.